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 @ 92dda2decaeebff72562a460a249ffa375262bd8 Lines: 439 461 95.2 %
Date: 2025-10-24 02:18:50 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      172196 : 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      172196 :     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      133254 :         test();
      84      133254 :         IF( ( EQ_16( sts[0]->core, TCX_10_CORE ) || ( NE_16( sts[0]->core, sts[1]->core ) ) ) )
      85             :         {
      86        3332 :             nSubframes = NB_DIV; /* Q0 */
      87        3332 :             move16();
      88             :         }
      89             :         ELSE
      90             :         {
      91      129922 :             nSubframes = 1; /* Q0 */
      92      129922 :             move16();
      93             :         }
      94      133254 :         move16();
      95             :         // sfbConf = ( EQ_16( sts[0]->core, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
      96      133254 :         IF( ( EQ_16( sts[0]->core, TCX_20_CORE ) ) )
      97             :         {
      98      130114 :             sfbConf = &hStereoMdct->stbParamsTCX20;
      99             :         }
     100             :         ELSE
     101             :         {
     102        3140 :             sfbConf = &hStereoMdct->stbParamsTCX10;
     103             :         }
     104      133254 :         if ( sts[0]->last_core_from_bs == ACELP_CORE )
     105             :         {
     106         631 :             sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
     107             :         }
     108             : 
     109      133254 :         IF( hStereoMdct->use_itd )
     110             :         {
     111             :             Word16 I;
     112             : 
     113       11448 :             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       11448 :             hStereoMdct->itd_fx = 0;
     117       11448 :             move32();
     118       11448 :             IF( hStereoMdct->itd_mode )
     119             :             {
     120        3458 :                 /*(*nb_bits) += */ read_itd( st0, &I );
     121        3458 :                 stereo_dft_dequantize_itd_fx( &I, &hStereoMdct->itd_fx, st0->output_Fs );
     122             :             }
     123             :         }
     124             : 
     125      269840 :         FOR( k = 0; k < nSubframes; k++ )
     126             :         {
     127      136586 :             mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
     128      136586 :             IF( mdct_stereo_mode )
     129             :             {
     130      132884 :                 mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
     131             :             }
     132      136586 :             SWITCH( mdct_stereo_mode )
     133             :             {
     134        3702 :                 case 0:
     135        3702 :                     hStereoMdct->mdct_stereo_mode[k] = SMDCT_DUAL_MONO; /* Q0 */
     136        3702 :                     move16();
     137        3702 :                     BREAK;
     138       82411 :                 case 1:
     139       82411 :                     hStereoMdct->mdct_stereo_mode[k] = SMDCT_MS_FULL; /* Q0 */
     140       82411 :                     move16();
     141       82411 :                     BREAK;
     142       50473 :                 case 2:
     143       50473 :                     hStereoMdct->mdct_stereo_mode[k] = SMDCT_BW_MS; /* Q0 */
     144       50473 :                     move16();
     145       50473 :                     BREAK;
     146           0 :                 default:
     147           0 :                     assert( !"Not supported stereo mode\n" );
     148             :             }
     149             : 
     150      136586 :             IF( !mct_on )
     151             :             {
     152       43356 :                 test();
     153       43356 :                 IF( EQ_16( sts[0]->core, sts[1]->core ) || k == 0 )
     154             :                 {
     155       43097 :                     hStereoMdct->global_ild[k] = extract_l( get_next_indice_fx( st0, SMDCT_GLOBAL_ILD_BITS ) ); /* Q0 */
     156       43097 :                     move16();
     157       43097 :                     assert( ( GT_16( hStereoMdct->global_ild[k], 0 ) ) && ( LT_16( hStereoMdct->global_ild[k], SMDCT_ILD_RANGE ) ) );
     158             :                 }
     159             :                 ELSE
     160             :                 {
     161         259 :                     hStereoMdct->global_ild[1] = hStereoMdct->global_ild[0]; /* Q0 */
     162         259 :                     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      136586 :             IF( ( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_MS_FULL ) ) )
     168             :             {
     169       82411 :                 set16_fx( ms_mask[k], 1, sfbConf->nBandsStereoCore );
     170             :             }
     171             :             ELSE
     172             :             {
     173       54175 :                 set16_fx( ms_mask[k], 0, sfbConf->nBandsStereoCore );
     174             :             }
     175             : 
     176      136586 :             IF( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_BW_MS ) )
     177             :             {
     178     2098842 :                 FOR( i = 0; i < sfbConf->nBandsStereoCore; i++ )
     179             :                 {
     180     2048369 :                     ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
     181     2048369 :                     move16();
     182             :                 }
     183             :             }
     184             : 
     185      136586 :             IF( st0->igf )
     186             :             {
     187       91112 :                 mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) );
     188       91112 :                 IF( mdct_stereo_mode )
     189             :                 {
     190       54135 :                     mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
     191             :                 }
     192             : 
     193       91112 :                 SWITCH( mdct_stereo_mode )
     194             :                 {
     195       36977 :                     case 0:
     196       36977 :                         hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
     197       36977 :                         move16();
     198       36977 :                         BREAK;
     199       39920 :                     case 1:
     200       39920 :                         hStereoMdct->IGFStereoMode[k] = SMDCT_MS_FULL; /* Q0 */
     201       39920 :                         move16();
     202       39920 :                         BREAK;
     203       14215 :                     case 2:
     204       14215 :                         hStereoMdct->IGFStereoMode[k] = SMDCT_BW_MS; /* Q0 */
     205       14215 :                         move16();
     206       14215 :                         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       91112 :                 IF( ( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) ) )
     213             :                 {
     214       39920 :                     set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 1, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
     215             :                 }
     216             :                 ELSE
     217             :                 {
     218       51192 :                     set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 0, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
     219             :                 }
     220             : 
     221       91112 :                 IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
     222             :                 {
     223       89963 :                     FOR( i = sfbConf->nBandsStereoCore; i < sfbConf->sfbCnt; i++ )
     224             :                     {
     225       75748 :                         ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
     226       75748 :                         move16();
     227             :                     }
     228             :                 }
     229             :             }
     230             :             ELSE
     231             :             {
     232       45474 :                 hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
     233       45474 :                 move16();
     234             :             }
     235             :         }
     236             :     }
     237             : 
     238      172196 :     IF( !mct_on )
     239             :     {
     240       80927 :         hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; /* Equal bits to both channels   Q0*/
     241       80927 :         move16();
     242       80927 :         hStereoMdct->split_ratio = extract_l( get_next_indice_fx( st0, SMDCT_NBBITS_SPLIT_RATIO ) ); /* Q0 */
     243             : 
     244       80927 :         assert( GT_16( hStereoMdct->split_ratio, 0 ) );
     245             :     }
     246             : 
     247             : 
     248      172196 :     return;
     249             : }
     250             : 
     251             : 
     252             : /*-------------------------------------------------------------------*
     253             :  * inverseBwMS()
     254             :  *
     255             :  * Band-wise M/S stereo processing
     256             :  *-------------------------------------------------------------------*/
     257             : 
     258     1460647 : 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    78303795 :     FOR( j = startLine; j < stopLine; j++ )
     270             :     {
     271    76843148 :         tmpValue = x0[j];
     272    76843148 :         move32();
     273    76843148 :         x0[j] = Mpy_32_32( L_add( x0[j], x1[j] ), norm_fac ); /* Qx */
     274    76843148 :         move32();
     275    76843148 :         x1[j] = Mpy_32_32( L_sub_sat( tmpValue, x1[j] ), norm_fac ); /* Qx */
     276    76843148 :         move32();
     277             :     }
     278             : 
     279     1460647 :     return;
     280             : }
     281             : 
     282             : 
     283             : /*-------------------------------------------------------------------*
     284             :  * inverseMS()
     285             :  *
     286             :  * M/S stereo processing
     287             :  *-------------------------------------------------------------------*/
     288             : 
     289      168537 : 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      168537 :     inverseBwMS_fx( 0, L_frame, x0, x1, norm_fac );
     297             : 
     298      168537 :     return;
     299             : }
     300             : 
     301             : 
     302             : /*-------------------------------------------------------------------*
     303             :  * stereo_decoder_tcx()
     304             :  *
     305             :  * apply stereo processing (inverse MS and global ILD)
     306             :  *-------------------------------------------------------------------*/
     307             : 
     308      134572 : 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      134572 :     STEREO_MDCT_BAND_PARAMETERS *sfbConf = NULL;
     328             :     Word32 nrgRatio, inv_nrgRatio, tmp_32;
     329             :     Word16 tmp_e, shift;
     330             : 
     331      134572 :     nSubframes = 2;
     332      134572 :     move16();
     333      134572 :     test();
     334      134572 :     test();
     335      134572 :     if ( ( LE_16( core_l, TCX_20_CORE ) && LE_16( core_r, TCX_20_CORE ) ) || tmp_plc_upmix )
     336             :     {
     337      131222 :         nSubframes = 1; /* Q0 */
     338      131222 :         move16();
     339             :     }
     340             : 
     341      272494 :     FOR( k = 0; k < nSubframes; k++ )
     342             :     {
     343             :         // sfbConf = ( EQ_16( core_l, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
     344      137922 :         IF( ( EQ_16( core_l, TCX_20_CORE ) ) )
     345             :         {
     346      131586 :             sfbConf = &hStereoMdct->stbParamsTCX20;
     347             :         }
     348             :         ELSE
     349             :         {
     350        6336 :             sfbConf = &hStereoMdct->stbParamsTCX10;
     351             :         }
     352             : 
     353      137922 :         test();
     354      137922 :         if ( last_core_l == ACELP_CORE || last_core_r == ACELP_CORE )
     355             :         {
     356         646 :             sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
     357             :         }
     358             : 
     359      137922 :         IF( EQ_16( mdct_stereo_mode[k], SMDCT_MS_FULL ) )
     360             :         {
     361    45417533 :             FOR( i = 0; i < sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i++ )
     362             :             {
     363    45334376 :                 IF( EQ_32( spec_r_0[k][i], 0 ) )
     364             :                 {
     365    12505428 :                     spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FX ); /* Qx */
     366    12505428 :                     move32();
     367             :                 }
     368             :             }
     369       83157 :             inverseMS_fx( sfbConf->sfbOffset[sfbConf->nBandsStereoCore], spec_l[k], spec_r[k], SQRT2_OVER_2_FX );
     370             :         }
     371       54765 :         ELSE IF( EQ_16( mdct_stereo_mode[k], SMDCT_BW_MS ) )
     372             :         {
     373     2119579 :             FOR( sfb = 0; sfb < sfbConf->nBandsStereoCore; sfb++ )
     374             :             {
     375     2068579 :                 IF( ms_mask[k][sfb] )
     376             :                 {
     377    17951852 :                     FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
     378             :                     {
     379    16699986 :                         IF( EQ_32( spec_r_0[k][i], 0 ) )
     380             :                         {
     381     4638796 :                             spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FX ); /* Qx */
     382     4638796 :                             move32();
     383             :                         }
     384             :                     }
     385     1251866 :                     inverseBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], spec_l[k], spec_r[k], SQRT2_OVER_2_FX );
     386             :                 }
     387             :             }
     388             :         }
     389             : 
     390      137922 :         IF( igf )
     391             :         {
     392       91774 :             IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) )
     393             :             {
     394    12156625 :                 FOR( i = sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i < sfbConf->sfbOffset[sfbConf->sfbCnt]; i++ )
     395             :                 {
     396    12116550 :                     IF( EQ_32( spec_r_0[k][i], 0 ) )
     397             :                     {
     398     3767009 :                         spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FX ); /* Qx */
     399     3767009 :                         move32();
     400             :                     }
     401             :                 }
     402       40075 :                 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       51699 :             ELSE IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
     405             :             {
     406       90491 :                 FOR( sfb = sfbConf->nBandsStereoCore; sfb < sfbConf->sfbCnt; sfb++ )
     407             :                 {
     408       76206 :                     IF( ms_mask[k][sfb] )
     409             :                     {
     410     2004870 :                         FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
     411             :                         {
     412     1964626 :                             IF( EQ_32( spec_r_0[k][i], 0 ) )
     413             :                             {
     414      697644 :                                 spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FX ); /* Qx */
     415      697644 :                                 move32();
     416             :                             }
     417             :                         }
     418       40244 :                         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      137922 :         IF( !mct_on )
     425             :         {
     426       44692 :             tmp_32 = BASOP_Util_Divide3232_Scale_newton( SMDCT_ILD_RANGE << 16, L_deposit_h( hStereoMdct->global_ild[k] ), &tmp_e );
     427       44692 :             tmp_32 = L_shr( tmp_32, sub( 5, tmp_e ) ); /* nrgRatio = nrg[1]/nrg[0] */ // Q26
     428       44692 :             nrgRatio = L_sub( tmp_32, ONE_IN_Q26 );                                   // Q26
     429             : 
     430       44692 :             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       44692 :             move32();
     432             :             /* set flag to reverse dmx computation in case of right-side panning, only relevant for mono output */
     433       44692 :             IF( GT_32( hStereoMdct->smooth_ratio_fx, ONE_POINT_3_FX ) )
     434             :             {
     435       16589 :                 hStereoMdct->reverse_dmx = 1; /* Q0 */
     436       16589 :                 move16();
     437             :             }
     438       28103 :             ELSE IF( LT_32( hStereoMdct->smooth_ratio_fx, POINT_9_FX ) )
     439             :             {
     440        8230 :                 hStereoMdct->reverse_dmx = 0; /* Q0 */
     441        8230 :                 move16();
     442             :             }
     443             : 
     444       44692 :             Word16 tmp1, tmp2 = 0;
     445             : 
     446       44692 :             IF( EQ_16( core_r, TCX_10_CORE ) )
     447             :             {
     448        2658 :                 tmp1 = NB_DIV;
     449        2658 :                 move16();
     450             :             }
     451             :             ELSE
     452             :             {
     453       42034 :                 tmp1 = 1;
     454       42034 :                 move16();
     455             :             }
     456             : 
     457       44692 :             IF( EQ_16( core_l, TCX_10_CORE ) )
     458             :             {
     459        2406 :                 tmp2 = NB_DIV;
     460        2406 :                 move16();
     461             :             }
     462             :             ELSE
     463             :             {
     464       42286 :                 tmp2 = 1;
     465       42286 :                 move16();
     466             :             }
     467             : 
     468       44692 :             test();
     469       44692 :             test();
     470       44692 :             IF( ( GT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp1 ) ) )
     471             :             {
     472       21684 :                 shift = norm_l( nrgRatio );
     473       21684 :                 nrgRatio = L_shl( nrgRatio, shift );                        /* Q26 + shift */
     474       21684 :                 v_multc_fx( spec_r[k], nrgRatio, spec_r[k], L_frameTCX_r ); /* spec_r will be in Qx + shift - Q5 */
     475       21684 :                 Scale_sig32( spec_r[k], L_frameTCX_r, sub( 5, shift ) );    /* Qx */
     476             :             }
     477       23008 :             ELSE IF( ( LT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp2 ) ) )
     478             :             {
     479        9627 :                 inv_nrgRatio = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q26, nrgRatio, &tmp_e );
     480        9627 :                 shift = sub( 5, tmp_e );
     481        9627 :                 v_multc_fx( spec_l[k], inv_nrgRatio, spec_l[k], L_frameTCX_l ); /* spec_r will be in Qx - tmp_e */
     482        9627 :                 Scale_sig32( spec_l[k], L_frameTCX_l, sub( 5, shift ) );        /* Qx */
     483             :             }
     484             :         }
     485             :     } /* for k */
     486             : 
     487      134572 :     return;
     488             : }
     489             : 
     490             : 
     491             : /*-------------------------------------------------------------------*
     492             :  * initMdctStereoDecData()
     493             :  *
     494             :  * Initialize MDCT stereo decoder configuration
     495             :  *-------------------------------------------------------------------*/
     496             : 
     497      298401 : 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      298401 :     tcx_coded_lines = getNumTcxCodedLines( bwidth );
     508             : 
     509             :     /*Initialize sfb parameteres for TCX20 */
     510      298401 :     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      298401 :     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      298401 :     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      298401 :     IF( igf )
     519             :     {
     520             :         /* calculate the igf start band from the igf start line */
     521      168327 :         stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20 ), 16384 /*1 Q14*/, bwidth, element_brate );
     522      168327 :         stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX10 ), 8192 /*0.50f Q14*/, bwidth, element_brate );
     523      168327 :         stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20afterACELP ), 20480 /*1.25 Q14*/, bwidth, element_brate );
     524             :     }
     525             :     ELSE
     526             :     {
     527      130074 :         hStereoMdct->stbParamsTCX20.sfbIgfStart = -1; /* Q0 */
     528      130074 :         move16();
     529      130074 :         hStereoMdct->stbParamsTCX10.sfbIgfStart = -1; /* Q0 */
     530      130074 :         move16();
     531      130074 :         hStereoMdct->stbParamsTCX20afterACELP.sfbIgfStart = -1; /* Q0 */
     532      130074 :         move16();
     533      130074 :         hStereoMdct->stbParamsTCX10.nBandsStereoCore = hStereoMdct->stbParamsTCX10.sfbCnt; /* Q0 */
     534      130074 :         move16();
     535      130074 :         hStereoMdct->stbParamsTCX20.nBandsStereoCore = hStereoMdct->stbParamsTCX20.sfbCnt; /* Q0 */
     536      130074 :         move16();
     537      130074 :         hStereoMdct->stbParamsTCX20afterACELP.nBandsStereoCore = hStereoMdct->stbParamsTCX20afterACELP.sfbCnt; /* Q0 */
     538      130074 :         move16();
     539             :     }
     540             : 
     541      298401 :     return;
     542             : }
     543             : 
     544             : 
     545             : /*-------------------------------------------------------------------*
     546             :  * initMdctStereoDtxData()
     547             :  *
     548             :  * Allocate and initialize structures for MDCT-Stereo DTX operation
     549             :  *-------------------------------------------------------------------*/
     550             : 
     551          31 : ivas_error initMdctStereoDtxData_fx(
     552             :     CPE_DEC_HANDLE hCPE /* i/o: CPE handle */
     553             : )
     554             : {
     555             :     Word16 ch;
     556             :     ivas_error error;
     557             : 
     558          31 :     error = IVAS_ERR_OK;
     559          31 :     move16();
     560             : 
     561          93 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
     562             :     {
     563          62 :         DEC_CORE_HANDLE st = hCPE->hCoreCoder[ch];
     564             : 
     565          62 :         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          62 :         IF( st->first_CNG == 0 )
     578             :         {
     579          58 :             test();
     580          58 :             IF( EQ_16( ch, 1 ) && st->cng_sba_flag )
     581             :             {
     582          17 :                 st->hFdCngDec->hFdCngCom->seed = add( st->hFdCngDec->hFdCngCom->seed, 3 ); /* Q0 */
     583          17 :                 move16();
     584             :             }
     585             :         }
     586             : 
     587          62 :         IF( st->cldfbAna == NULL )
     588             :         {
     589             :             /* open analysis for max. sampling rate 48kHz */
     590          50 :             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          62 :         IF( st->cldfbBPF == NULL )
     597             :         {
     598             :             /* open analysis BPF for max. internal sampling rate 16kHz */
     599          50 :             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          31 :     return error;
     607             : }
     608             : 
     609             : 
     610             : /*-------------------------------------------------------------------*
     611             :  * synchonize_channels_mdct_sid()
     612             :  *
     613             :  * Synchronize channels in SID frame in MDCT stereo
     614             :  *-------------------------------------------------------------------*/
     615             : 
     616     1110856 : 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     1110856 :     st = sts[n];
     624             : 
     625     1110856 :     test();
     626     1110856 :     IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_32( st->total_brate, SID_2k40 ) )
     627             :     {
     628         892 :         IF( EQ_16( n, 1 ) )
     629             :         {
     630             :             /* synchronize channels */
     631         446 :             sts[1]->L_frame = sts[0]->L_frame;
     632         446 :             move16();
     633         446 :             sts[1]->cng_type = sts[0]->cng_type;
     634         446 :             move16();
     635         446 :             sts[1]->bwidth = sts[0]->bwidth;
     636         446 :             move16();
     637         446 :             sts[0]->hFdCngDec->hFdCngCom->coherence_fx = sts[1]->hFdCngDec->hFdCngCom->coherence_fx; /* coherence is stored in sts[1] - see ivas_decision_matrix_dec() */
     638         446 :             move16();
     639         446 :             sts[0]->hFdCngDec->hFdCngCom->no_side_flag = sts[1]->hFdCngDec->hFdCngCom->no_side_flag;
     640         446 :             move16();
     641             : 
     642             :             /* configure when there is a switching from DFT CNG to MDCT CNG */
     643         446 :             test();
     644         446 :             IF( EQ_16( sts[0]->first_CNG, 1 ) && EQ_16( sts[1]->first_CNG, 0 ) )
     645             :             {
     646           0 :                 configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode );
     647             :             }
     648             :         }
     649             : 
     650         892 :         IF( sts[0]->first_CNG == 0 )
     651             :         {
     652             :             /* 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 */
     653          58 :             configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode );
     654             :         }
     655             :     }
     656             : 
     657     1110856 :     return;
     658             : }
     659             : 
     660             : 
     661             : /*-------------------------------------------------------------------*
     662             :  * updateBuffersForDmxMdctStereo()
     663             :  *
     664             :  * synch buffers between channels for mono output and
     665             :  * apply passive downmix to certain buffers to enable smooth transitions
     666             :  * between active/inactive coding in MDCT-Stereo DTX
     667             :  *-------------------------------------------------------------------*/
     668             : 
     669        3243 : static void update_exp(
     670             :     Word16 *a_exp,
     671             :     Word16 *b_exp,
     672             :     Word16 *buff_a,    /* exp(a_exp) */
     673             :     Word16 *buff_b,    /* exp(b_exp) */
     674             :     const Word16 legth /* Q0 */
     675             : )
     676             : {
     677        3243 :     Word16 diff = 0;
     678        3243 :     move16();
     679        3243 :     IF( GT_16( *a_exp, *b_exp ) )
     680             :     {
     681        1026 :         diff = sub( *a_exp, *b_exp );
     682      981246 :         FOR( Word16 j = 0; j < legth; j++ )
     683             :         {
     684      980220 :             buff_b[j] = shr( buff_b[j], diff ); /* exp(a_exp) */
     685      980220 :             move16();
     686             :         }
     687        1026 :         *b_exp = *a_exp;
     688        1026 :         move16();
     689             :     }
     690        2217 :     ELSE IF( LT_16( *a_exp, *b_exp ) )
     691             :     {
     692          36 :         diff = sub( *b_exp, *a_exp );
     693             : 
     694       18480 :         FOR( Word16 j = 0; j < legth; j++ )
     695             :         {
     696       18444 :             buff_a[j] = shr( buff_a[j], diff ); /* exp(b_exp)*/
     697       18444 :             move16();
     698             :         }
     699          36 :         *a_exp = *b_exp;
     700          36 :         move16();
     701             :     }
     702        3243 :     return;
     703             : }
     704             : 
     705        1120 : void updateBuffersForDmxMdctStereo_fx(
     706             :     CPE_DEC_HANDLE hCPE,                      /* i/o: CPE handle                              */
     707             :     const Word16 output_frame,                /* i  : output frame length                   Q0*/
     708             :     Word32 output0_fx[],                      /* Qx */
     709             :     Word32 output1_fx[],                      /* Qx */
     710             :     Word16 synth_fx[CPE_CHANNELS][L_FRAME48k] /* i/o: decoder synthesis                 qsynth*/
     711             : )
     712             : {
     713             :     Word16 delay_buf_out_len, tcxltp_mem_in_len, delta, i;
     714             :     Decoder_State *sts[CPE_CHANNELS];
     715             : 
     716        1120 :     sts[0] = hCPE->hCoreCoder[0];
     717        1120 :     sts[1] = hCPE->hCoreCoder[1];
     718             : 
     719             :     /* synch buffers for inactive frames, but not for transition frames */
     720        1120 :     IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     721             :     {
     722        1081 :         Copy32( output0_fx, output1_fx, output_frame );
     723        1081 :         Copy( synth_fx[0], synth_fx[1], output_frame );
     724             :     }
     725             : 
     726        1120 :     Word32 Var1 = 0;
     727        1120 :     move16();
     728        1120 :     Word16 diff_sidNoiseEst = 0;
     729        1120 :     move16();
     730        1120 :     Word16 exp_sidNoiseEst0 = sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp;
     731        1120 :     move16();
     732        1120 :     Word16 exp_sidNoiseEst1 = sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp;
     733        1120 :     move16();
     734        1120 :     IF( GT_16( exp_sidNoiseEst0, exp_sidNoiseEst1 ) )
     735             :     {
     736          14 :         diff_sidNoiseEst = sub( exp_sidNoiseEst0, exp_sidNoiseEst1 );
     737         350 :         FOR( Word32 j = 0; j < NPART; j++ )
     738             :         {
     739         336 :             sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[j] = L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[j], diff_sidNoiseEst ); /* exp(exp_sidNoiseEst0) */
     740         336 :             move16();
     741             :         }
     742          14 :         exp_sidNoiseEst1 = exp_sidNoiseEst0;
     743          14 :         move16();
     744             :     }
     745        1106 :     ELSE IF( LT_16( exp_sidNoiseEst0, exp_sidNoiseEst1 ) )
     746             :     {
     747          10 :         diff_sidNoiseEst = sub( exp_sidNoiseEst1, exp_sidNoiseEst0 );
     748         250 :         FOR( Word32 j = 0; j < NPART; j++ )
     749             :         {
     750         240 :             sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[j] = L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[j], diff_sidNoiseEst ); /* exp( exp_sidNoiseEst1) */
     751         240 :             move16();
     752             :         }
     753          10 :         exp_sidNoiseEst0 = exp_sidNoiseEst1;
     754          10 :         move16();
     755             :     }
     756        1120 :     sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = exp_sidNoiseEst0;
     757        1120 :     move16();
     758        1120 :     sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp = exp_sidNoiseEst1;
     759        1120 :     move16();
     760        1120 :     test();
     761        1120 :     test();
     762        1120 :     IF( EQ_32( hCPE->element_brate, IVAS_SID_5k2 ) && GT_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     763             :     {
     764             :         /* 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 */
     765         948 :         FOR( Word16 p = 0; p < sts[0]->hFdCngDec->hFdCngCom->npart; p++ )
     766             :         {
     767         909 :             Var1 = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); // exp_sidNoiseEst0 - 1
     768         909 :             sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = Mpy_32_32( ONE_IN_Q30, Var1 );                                                       //  31 - exp_sidNoiseEst0 - 1 + 31 - 31
     769         909 :             move32();
     770             :         }
     771             :     }
     772             : 
     773             :     /* for transition of active->inactive frame, apply passive downmix on buffers */
     774        1120 :     IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     775             :     {
     776        1081 :         delta = 1;
     777        1081 :         move16();
     778        1081 :         IF( EQ_16( output_frame, L_FRAME16k ) )
     779             :         {
     780         349 :             delta = 2;
     781         349 :             move16();
     782             :         }
     783         732 :         ELSE IF( EQ_16( output_frame, L_FRAME32k ) )
     784             :         {
     785         358 :             delta = 4;
     786         358 :             move16();
     787             :         }
     788         374 :         ELSE IF( EQ_16( output_frame, L_FRAME48k ) )
     789             :         {
     790         374 :             delta = 6;
     791         374 :             move16();
     792             :         }
     793             : 
     794        1081 :         delay_buf_out_len = i_mult( delta, HQ_DELAY_COMP );                  /* Q0 */
     795        1081 :         tcxltp_mem_in_len = NS2SA_FX2( sts[0]->output_Fs, TCXLTP_DELAY_NS ); /* Q0 */
     796        1081 :         move16();
     797             : 
     798        1081 :         assert( delay_buf_out_len > tcxltp_mem_in_len );
     799             : 
     800        1081 :         Word16 sum_tcx_ltp = 0, sum_delay_buf = 0, sum_tcx_ltp_out = 0, sum_old_out = 0;
     801        1081 :         move16();
     802        1081 :         move16();
     803        1081 :         move16();
     804        1081 :         move16();
     805             : 
     806        1081 :         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
     807        1081 :         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
     808             : 
     809        1081 :         Copy_Scale_sig_32_16( &sts[0]->hTcxLtpDec->tcxltp_mem_out_32[0], &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], L_FRAME48k, -11 ); // Q0
     810        1081 :         Copy_Scale_sig_32_16( &sts[1]->hTcxLtpDec->tcxltp_mem_out_32[0], &sts[1]->hTcxLtpDec->tcxltp_mem_out[0], L_FRAME48k, -11 ); // Q0
     811             : 
     812        1081 :         sts[0]->hTcxLtpDec->exp_tcxltp_mem_in = sub( 15, norm_arr( sts[0]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY ) );
     813        1081 :         move16();
     814        1081 :         sts[1]->hTcxLtpDec->exp_tcxltp_mem_in = sub( 15, norm_arr( sts[1]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY ) );
     815        1081 :         move16();
     816             : 
     817        1081 :         sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = sub( 15, norm_arr( sts[0]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k ) );
     818        1081 :         move16();
     819        1081 :         sts[1]->hTcxLtpDec->exp_tcxltp_mem_out = sub( 15, norm_arr( sts[1]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k ) );
     820        1081 :         move16();
     821             : 
     822             : 
     823        1081 :         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)
     824        1081 :         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)
     825             : 
     826        1081 :         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)
     827        1081 :         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)
     828             : 
     829             : 
     830        1081 :         update_exp( &sts[0]->hTcxLtpDec->exp_tcxltp_mem_in, &sts[1]->hTcxLtpDec->exp_tcxltp_mem_in,
     831        1081 :                     sts[0]->hTcxLtpDec->tcxltp_mem_in, sts[1]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY );
     832             : 
     833        1081 :         update_exp( &sts[0]->hHQ_core->exp_old_out, &sts[1]->hHQ_core->exp_old_out,
     834        1081 :                     sts[0]->hHQ_core->old_out_fx, sts[1]->hHQ_core->old_out_fx, L_FRAME48k );
     835             : 
     836        1081 :         update_exp( &sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, &sts[1]->hTcxLtpDec->exp_tcxltp_mem_out,
     837        1081 :                     sts[0]->hTcxLtpDec->tcxltp_mem_out, sts[1]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k );
     838             : 
     839        9829 :         FOR( i = 0; i < tcxltp_mem_in_len; i++ )
     840             :         {
     841        8748 :             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
     842        8748 :             sts[0]->hTcxLtpDec->tcxltp_mem_in[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp );                                        //  exp_tcxltp_mem_in + 1
     843        8748 :             move16();
     844             : 
     845        8748 :             sum_delay_buf = add( sts[0]->delay_buf_out_fx[i], sts[1]->delay_buf_out_fx[i] ); /* Q0 */
     846        8748 :             sts[0]->delay_buf_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_delay_buf );           // Q0
     847        8748 :             move16();
     848             : 
     849        8748 :             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
     850        8748 :             sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out );                                   // exp_old_out + 1
     851        8748 :             move16();
     852             : 
     853        8748 :             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
     854        8748 :             sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out );                                         // exp_tcxltp_mem_out + 1
     855        8748 :             move16();
     856             :         }
     857             : 
     858             : 
     859       36073 :         FOR( ; i < delay_buf_out_len; i++ )
     860             :         {
     861       34992 :             sum_delay_buf = add( sts[0]->delay_buf_out_fx[i], sts[1]->delay_buf_out_fx[i] ); // Q0
     862       34992 :             sts[0]->delay_buf_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_delay_buf );           // Q0
     863       34992 :             move16();
     864             : 
     865       34992 :             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 */
     866       34992 :             sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out );                                   /* exp_old_out + 1 */
     867       34992 :             move16();
     868             : 
     869       34992 :             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
     870       34992 :             sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out );                                         // exp_tcxltp_mem_out + 1
     871       34992 :             move16();
     872             :         }
     873             : 
     874      657181 :         FOR( ; i < output_frame; i++ )
     875             :         {
     876      656100 :             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
     877      656100 :             sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out );                                   // exp_old_out + 1
     878      656100 :             move16();
     879             : 
     880      656100 :             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
     881      656100 :             sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out );                                         // exp_tcxltp_mem_out + 1
     882      656100 :             move16();
     883             :         }
     884        1081 :         sts[0]->hTcxLtpDec->exp_tcxltp_mem_in = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_in, 1 );
     885        1081 :         move16();
     886        1081 :         sts[0]->hHQ_core->exp_old_out = add( sts[0]->hHQ_core->exp_old_out, 1 );
     887        1081 :         move16();
     888        1081 :         sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, 1 );
     889        1081 :         move16();
     890        1081 :         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
     891        1081 :         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
     892             :     }
     893             : 
     894        1120 :     return;
     895             : }
     896             : 
     897             : 
     898             : /*-------------------------------------------------------------------*
     899             :  * applyDmxMdctStereo()
     900             :  *
     901             :  * apply passive downmix to certain buffers to enable smooth transitions
     902             :  * between active/inactive coding in MDCT-Stereo DTX
     903             :  *-------------------------------------------------------------------*/
     904             : 
     905        5917 : void applyDmxMdctStereo_fx(
     906             :     const CPE_DEC_HANDLE hCPE,       /* i  : CPE handle                                    */
     907             :     Word32 *output_fx[CPE_CHANNELS], /* i/o: core decoder output          q_out*/
     908             :     const Word16 output_frame        /* i  : output frame length                 Q0*/
     909             : )
     910             : {
     911             :     Word16 crossfade_len, i;
     912             :     Word16 dmx_len;
     913             :     Word32 fade_fx, step_fx;
     914             : 
     915        5917 :     step_fx = ONE_IN_Q31; /* Q31 */
     916        5917 :     move32();
     917        5917 :     fade_fx = ONE_IN_Q31; /* Q31 */
     918        5917 :     move32();
     919        5917 :     dmx_len = output_frame; /* Q0 */
     920        5917 :     move16();
     921             : 
     922        5917 :     test();
     923        5917 :     test();
     924        5917 :     IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     925             :     {
     926          35 :         crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS );
     927          35 :         move16();
     928          35 :         SWITCH( hCPE->hCoreCoder[0]->output_Fs )
     929             :         {
     930          15 :             case 48000:
     931          15 :                 step_fx = 22369622; /* 0.0104 in Q31 */
     932          15 :                 move32();
     933          15 :                 BREAK;
     934          12 :             case 32000:
     935          12 :                 step_fx = 33554432; /* 0.0156 in Q31 */
     936          12 :                 move32();
     937          12 :                 BREAK;
     938           8 :             case 16000:
     939           8 :                 step_fx = 67108864; /* 0.0312 in Q31 */
     940           8 :                 move32();
     941           8 :                 BREAK;
     942           0 :             default:
     943           0 :                 assert( 0 );
     944             :                 BREAK;
     945             :         }
     946             :     }
     947             :     /* for first inactive CNG frame after active decoding we have to do a fade-OUT FROM the passive DMX */
     948        5882 :     ELSE IF( LE_32( hCPE->element_brate, IVAS_SID_5k2 ) && GT_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     949             :     {
     950          39 :         crossfade_len = shr( output_frame, 2 ); /* Q0 */
     951          39 :         SWITCH( output_frame )
     952             :         {
     953          17 :             case 960:
     954          17 :                 step_fx = -8947849; /* -0.0041 in Q31 */
     955          17 :                 move32();
     956          17 :                 BREAK;
     957          13 :             case 640:
     958          13 :                 step_fx = -13421773; /* -0.00625 in Q31 */
     959          13 :                 move32();
     960          13 :                 BREAK;
     961           9 :             case 320:
     962           9 :                 step_fx = -26843546; /* -0.0125 in Q31 */
     963           9 :                 move32();
     964           9 :                 BREAK;
     965             :         }
     966          39 :         fade_fx = 0;
     967          39 :         move32();
     968          39 :         dmx_len = crossfade_len; /* Q0 */
     969          39 :         move16();
     970             :     }
     971        5843 :     ELSE IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && LE_32( hCPE->last_element_brate, IVAS_32k ) )
     972             :     {
     973          15 :         crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, DELAY_CLDFB_NS ); /* Q0 */
     974          15 :         move16();
     975          15 :         SWITCH( hCPE->hCoreCoder[0]->output_Fs )
     976             :         {
     977          15 :             case 48000:
     978          15 :                 step_fx = 35791396; /* 0.0166 in Q31 */
     979          15 :                 move32();
     980          15 :                 BREAK;
     981           0 :             case 32000:
     982           0 :                 step_fx = 53687092; /* 0.025 in Q31 */
     983           0 :                 move32();
     984           0 :                 BREAK;
     985           0 :             case 16000:
     986           0 :                 step_fx = 107374184; /* 0.05 in Q31 */
     987           0 :                 move32();
     988           0 :                 BREAK;
     989           0 :             default:
     990           0 :                 assert( 0 );
     991             :                 BREAK;
     992             :         }
     993             :     }
     994             :     ELSE
     995             :     {
     996        5828 :         crossfade_len = 0;
     997        5828 :         move16();
     998             :     }
     999             : 
    1000             :     /* apply crossfade */
    1001       16161 :     FOR( i = 0; i < crossfade_len; i++ )
    1002             :     {
    1003       10244 :         Word32 temp_1 = Mpy_32_32( output_fx[0][i], fade_fx );                                                                                   /* q_out */
    1004       10244 :         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 */
    1005       10244 :         output_fx[0][i] = L_add( temp_1, temp_2 );                                                                                               /* q_out */
    1006       10244 :         move32();
    1007       10244 :         fade_fx = L_sub_sat( fade_fx, step_fx ); /* Q31 */
    1008             :     }
    1009             : 
    1010             :     /* apply passive downmix on all-active-frame part */
    1011     4601913 :     FOR( ; i < dmx_len; i++ )
    1012             :     {
    1013     4595996 :         output_fx[0][i] = Mpy_32_32( L_add_sat( output_fx[0][i], output_fx[1][i] ), INV_SQRT2_FX ); /* q_out */
    1014     4595996 :         move32();
    1015             :     }
    1016             : 
    1017        5917 :     return;
    1018             : }

Generated by: LCOV version 1.14