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

Generated by: LCOV version 1.14