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 -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 439 461 95.2 %
Date: 2025-08-23 01:22:27 Functions: 10 10 100.0 %

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

Generated by: LCOV version 1.14