LCOV - code coverage report
Current view: top level - lib_dec - ivas_mct_dec_mct_fx_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 161 164 98.2 %
Date: 2025-08-23 01:22:27 Functions: 5 5 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 <stdint.h>
      34             : #include "options.h"
      35             : #include "ivas_cnst.h"
      36             : #include "prot_fx.h"
      37             : #include "wmc_auto.h"
      38             : #include <assert.h>
      39             : #include "stat_enc.h"
      40             : #include "ivas_prot_fx.h"
      41             : 
      42             : /*----------------------------------------------------------*
      43             :  * indexToChannelPair()
      44             :  *
      45             :  * get the index of each channel pair
      46             :  *----------------------------------------------------------*/
      47             : 
      48       89017 : static void indexToChannelPair_fx(
      49             :     MCT_DEC_BLOCK_DATA_HANDLE hBlock,
      50             :     const Word16 nChannels,
      51             :     const Word16 pairIdx )
      52             : {
      53             :     Word16 ch1, ch2;
      54       89017 :     Word16 tmpIdx = 0;
      55       89017 :     move16();
      56             : 
      57      336812 :     FOR( ch2 = 1; ch2 < nChannels; ch2++ )
      58             :     {
      59     1085680 :         FOR( ch1 = 0; ch1 < ch2; ch1++ )
      60             :         {
      61      837885 :             IF( EQ_16( tmpIdx, pairIdx ) )
      62             :             {
      63       89017 :                 hBlock->ch1 = ch1;
      64       89017 :                 move16();
      65       89017 :                 hBlock->ch2 = ch2;
      66       89017 :                 move16();
      67             : 
      68       89017 :                 return;
      69             :             }
      70             :             ELSE
      71             :             {
      72      748868 :                 tmpIdx = add( tmpIdx, 1 );
      73             :             }
      74             :         }
      75             :     }
      76             : 
      77           0 :     return;
      78             : }
      79             : 
      80             : 
      81             : /*-------------------------------------------------------------------*
      82             :  * ivas_mct_dec_mct()
      83             :  *
      84             :  * decode core and mct information
      85             :  *-------------------------------------------------------------------*/
      86             : 
      87       96687 : void ivas_mct_dec_mct_fx(
      88             :     MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure       */
      89             :     Decoder_State **sts, /* i/o: decoder state structure     */
      90             :     const Word16 nchan   /* i  : number of channels          */
      91             : )
      92             : {
      93             :     Word16 pair, ch, channelPairIndex;
      94             :     MCT_DEC_BLOCK_DATA_HANDLE hBlock;
      95             :     Decoder_State *p_st[CPE_CHANNELS];
      96       96687 :     Word16 nchan_active = 0;
      97       96687 :     move16();
      98             : 
      99       96687 :     hMCT->currBlockDataCnt = get_next_indice_fx( sts[0], MCT_NUM_BLOCK_DATA_BITS );
     100       96687 :     move16();
     101             : 
     102             :     /*first get core and overlap info for all channels*/
     103      554629 :     FOR( ch = 0; ch < nchan; ch++ )
     104             :     {
     105      457942 :         test();
     106      457942 :         IF( hMCT->currBlockDataCnt && NE_16( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
     107             :         {
     108      277020 :             hMCT->mc_global_ild[ch] = get_next_indice_fx( sts[0], SMDCT_GLOBAL_ILD_BITS );
     109      277020 :             move16();
     110             :         }
     111             :         ELSE
     112             :         {
     113      180922 :             hMCT->mc_global_ild[ch] = 0;
     114      180922 :             move16();
     115             :         }
     116             :     }
     117             : 
     118       96687 :     IF( hMCT->currBlockDataCnt )
     119             :     {
     120      334378 :         FOR( ch = 0; ch < nchan; ch++ )
     121             :         {
     122      280268 :             IF( NE_16( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
     123             :             {
     124      277020 :                 hMCT->lowE_ch[ch] = get_next_indice_fx( sts[0], 1 );
     125      277020 :                 move16();
     126             :             }
     127             :         }
     128             :     }
     129             : 
     130      554629 :     FOR( ch = 0; ch < nchan; ch++ )
     131             :     {
     132      457942 :         if ( NE_16( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
     133             :         {
     134      449471 :             nchan_active = add( nchan_active, 1 );
     135             :         }
     136             :     }
     137             : 
     138      185704 :     FOR( pair = hMCT->currBlockDataCnt - 1; pair >= 0; pair-- )
     139             :     {
     140       89017 :         assert( GE_16( nchan_active, 2 ) );
     141       89017 :         hBlock = hMCT->hBlockData[pair];
     142             : 
     143             :         /*get channel pair index from BS*/
     144       89017 :         channelPairIndex = get_next_indice_fx( sts[0], hMCT->bitsChannelPairIndex );
     145       89017 :         indexToChannelPair_fx( hBlock, nchan, channelPairIndex );
     146             : 
     147             :         /*point to decoder states of actual channels to read block pair bits*/
     148       89017 :         p_st[0] = sts[hBlock->ch1];
     149       89017 :         p_st[1] = sts[hBlock->ch2];
     150             : 
     151       89017 :         parse_stereo_from_bitstream( hBlock->hStereoMdct, p_st, 1, 0, sts[0], hBlock->mask );
     152             :     }
     153             : 
     154       96687 :     return;
     155             : }
     156             : 
     157             : 
     158             : /*----------------------------------------------------------*
     159             :  * applyGlobalILD()
     160             :  *
     161             :  * revert to initial channel energy levels using the ratios
     162             :  * sent from the encoder
     163             :  *----------------------------------------------------------*/
     164             : 
     165       96687 : static void applyGlobalILD_fx(
     166             :     Decoder_State **sts,
     167             :     MCT_DEC_HANDLE hMCT,
     168             :     Word32 *x[MCT_MAX_CHANNELS][NB_DIV] )
     169             : {
     170             :     Word16 ch, k;
     171             :     Word16 nSubframes, L_subframeTCX;
     172             :     Word32 qratio;
     173             :     Word16 q_qratio;
     174             :     Word16 tmp, tmp_e;
     175             : 
     176      554629 :     FOR( ch = 0; ch < ( hMCT->nchan_out_woLFE ); ch++ )
     177             :     {
     178      457942 :         IF( EQ_16( sts[ch]->core, TCX_20_CORE ) )
     179             :         {
     180      447805 :             nSubframes = 1;
     181      447805 :             move16();
     182             :         }
     183             :         ELSE
     184             :         {
     185       10137 :             nSubframes = NB_DIV;
     186       10137 :             move16();
     187             :         }
     188      457942 :         tmp = BASOP_Util_Divide1616_Scale( sts[ch]->hTcxDec->L_frameTCX, nSubframes, &tmp_e );
     189      457942 :         L_subframeTCX = shr( tmp, add( 15, negate( tmp_e ) ) );
     190             : 
     191      457942 :         IF( hMCT->mc_global_ild[ch] )
     192             :         {
     193      178034 :             IF( hMCT->lowE_ch[ch] )
     194             :             {
     195             :                 /* qratio = (float) hMCT->mc_global_ild[ch] / SMDCT_ILD_RANGE; */
     196      110607 :                 qratio = L_shl( hMCT->mc_global_ild[ch], Q26 - SMDCT_GLOBAL_ILD_BITS ); /* Q26 */
     197             :             }
     198             :             ELSE
     199             :             {
     200       67427 :                 tmp = BASOP_Util_Divide3216_Scale( ( SMDCT_ILD_RANGE << Q26 ), hMCT->mc_global_ild[ch], &tmp_e );
     201       67427 :                 qratio = L_shr( (Word32) tmp, negate( add( 1, tmp_e ) ) ); // Q26
     202             :             }
     203             : 
     204      178034 :             q_qratio = norm_l( qratio );
     205      178034 :             qratio = L_shl( qratio, q_qratio );
     206      359954 :             FOR( k = 0; k < nSubframes; k++ )
     207             :             {
     208      181920 :                 v_multc_fixed( x[ch][k], qratio, x[ch][k], L_subframeTCX ); // Qx - 5 + q_qratio
     209      181920 :                 scale_sig32( x[ch][k], L_subframeTCX, sub( 5, q_qratio ) );
     210             :             }
     211             :         }
     212             :         ELSE
     213             :         {
     214      279908 :             CONTINUE;
     215             :         }
     216             :     }
     217             : 
     218       96687 :     return;
     219             : }
     220             : 
     221             : 
     222             : /*----------------------------------------------------------*
     223             :  * apply_MCT_dec()
     224             :  *
     225             :  * main MCT decoding function
     226             :  *----------------------------------------------------------*/
     227             : 
     228       96687 : void apply_MCT_dec_fx(
     229             :     MCT_DEC_HANDLE hMCT,                /* i/o: MCT decoder structure                   */
     230             :     Decoder_State **sts,                /* i/o: decoder state structure                 */
     231             :     Word32 *x[MCT_MAX_CHANNELS][NB_DIV] /* i/o: decoded and dequan. spect. input to MCT */
     232             : )
     233             : {
     234             :     Word16 pair;
     235             :     MCT_DEC_BLOCK_DATA_HANDLE hBlock;
     236             : 
     237      185704 :     FOR( pair = hMCT->currBlockDataCnt - 1; pair >= 0; pair-- )
     238             :     {
     239       89017 :         hBlock = hMCT->hBlockData[pair];
     240             : 
     241       89017 :         stereo_decoder_tcx_fx( hBlock->hStereoMdct, hBlock->mask, &x[hBlock->ch2][0], &x[hBlock->ch1][0], &x[hBlock->ch2][0], hBlock->hStereoMdct->mdct_stereo_mode, sts[hBlock->ch1]->core, sts[hBlock->ch2]->core, sts[0]->igf, sts[0]->hTcxDec->L_frameTCX, sts[1]->hTcxDec->L_frameTCX, 1, TCX_20_CORE, TCX_20_CORE, 0 );
     242             :     }
     243             : 
     244       96687 :     applyGlobalILD_fx( sts, hMCT, x );
     245             : 
     246       96687 :     return;
     247             : }
     248             : 
     249             : /*----------------------------------------------------------*
     250             :  * mctStereoIGF_dec()
     251             :  *
     252             :  * apply IGF to MCT stereo block pairs
     253             :  *----------------------------------------------------------*/
     254             : 
     255       33709 : void mctStereoIGF_dec_fx(
     256             :     MCT_DEC_HANDLE hMCT,                 /* i/o: MCT decoder structure           */
     257             :     Decoder_State **stm,                 /* i/o: decoder state structure         */
     258             :     Word32 *x[MCT_MAX_CHANNELS][NB_DIV], /* i/o: decoded and dequantized spectrum i:Q12*/
     259             :     const Word16 bfi                     /* i  : bad frame flag                  */
     260             : )
     261             : {
     262             :     Word16 b, core, nSubframes, k, ch, p_ch[CPE_CHANNELS], ch1, ch2;
     263       33709 :     Decoder_State *sts[CPE_CHANNELS], *st = NULL;
     264             :     Word16 tcx_offset[CPE_CHANNELS];
     265             :     Word16 tcx_offsetFB[CPE_CHANNELS];
     266             :     Word16 left_rect[CPE_CHANNELS];
     267             :     Word16 L_spec[CPE_CHANNELS];
     268             :     Word16 L_frame[CPE_CHANNELS];
     269             :     Word16 L_frameTCX[CPE_CHANNELS];
     270             :     Word32 *p_x[CPE_CHANNELS][NB_DIV]; // Q(31 - p_x_e)
     271             :     Word16 p_x_e[CPE_CHANNELS][NB_DIV];
     272             :     Word16 p_x_len[CPE_CHANNELS][NB_DIV];
     273             :     Word16 singleChEle[MCT_MAX_CHANNELS];
     274             :     Word16 tmp_e;
     275             :     Word16 L_frame_nSubframe, L_frameTCX_nSubframe, tmp;
     276             : 
     277             : 
     278       33709 :     set16_fx( singleChEle, 1, ( hMCT->nchan_out_woLFE ) );
     279             : 
     280       91683 :     FOR( b = 0; b < hMCT->currBlockDataCnt; b++ )
     281             :     {
     282       57974 :         ch1 = hMCT->hBlockData[b]->ch1;
     283       57974 :         move16();
     284       57974 :         ch2 = hMCT->hBlockData[b]->ch2;
     285       57974 :         move16();
     286             : 
     287       57974 :         sts[0] = stm[ch1];
     288       57974 :         sts[1] = stm[ch2];
     289       57974 :         core = sts[0]->core;
     290       57974 :         move16();
     291       57974 :         nSubframes = core;
     292       57974 :         move16();
     293       57974 :         p_ch[0] = ch1;
     294       57974 :         move16();
     295       57974 :         p_ch[1] = ch2;
     296       57974 :         move16();
     297       57974 :         singleChEle[hMCT->hBlockData[b]->ch1] = 0;
     298       57974 :         move16();
     299       57974 :         singleChEle[hMCT->hBlockData[b]->ch2] = 0;
     300       57974 :         move16();
     301             : 
     302             :         // Using input Q-factor as 12
     303       57974 :         set16_fx( p_x_e[0], 31 - Q11, CPE_CHANNELS ); // Q12
     304       57974 :         set16_fx( p_x_e[1], 31 - Q11, CPE_CHANNELS ); // Q12
     305             : 
     306      117395 :         FOR( k = 0; k < nSubframes; k++ )
     307             :         {
     308       59421 :             p_x[0][k] = x[ch1][k]; // Q12
     309       59421 :             p_x[1][k] = x[ch2][k]; // Q12
     310             : 
     311       59421 :             test();
     312       59421 :             IF( NE_16( hMCT->hBlockData[b]->hStereoMdct->IGFStereoMode[k], SMDCT_DUAL_MONO ) || NE_16( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[k], SMDCT_DUAL_MONO ) )
     313       59401 :             {
     314             :                 Word16 shr_div, shr_k;
     315             : 
     316       59401 :                 assert( nSubframes == 1 || nSubframes == 2 );
     317             :                 /* Note: nSubframes is in limited range [1, 2] for this function */
     318             : 
     319       59401 :                 shr_div = sub( nSubframes, 1 ); /* 2 -> 1, 1 -> 0 */
     320       59401 :                 L_spec[0] = shr( sts[0]->hTcxCfg->tcx_coded_lines, shr_div );
     321       59401 :                 move16();
     322       59401 :                 L_frame_nSubframe = shr( sts[0]->L_frame, shr_div );
     323       59401 :                 L_frameTCX_nSubframe = shr( sts[0]->hTcxDec->L_frameTCX, shr_div );
     324             : 
     325       59401 :                 init_tcx_info_fx( sts[0], L_frame_nSubframe, L_frameTCX_nSubframe, k, bfi, &tcx_offset[0], &tcx_offsetFB[0], &L_frame[0], &L_frameTCX[0], &left_rect[0], &L_spec[0] );
     326             : 
     327             :                 /* stereo IGF decoding */
     328       59401 :                 assert( ( EQ_16( sts[0]->core, sts[1]->core ) ) || ( ( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO ) ) );
     329             : 
     330       59401 :                 decoder_tcx_IGF_stereo_fx( sts, hMCT->hBlockData[b]->hStereoMdct, hMCT->hBlockData[b]->mask, p_x, p_x_e, p_x_len, L_frame[0], left_rect[0], k, bfi, 1 /* MCT_flag */ );
     331             : 
     332             :                 // Shifting output with variable exponent back to Q12
     333       59401 :                 shr_k = sub( 31 - Q11, p_x_e[0][k] );
     334    45284361 :                 FOR( Word16 i = 0; i < p_x_len[0][k]; i++ )
     335             :                 {
     336    45224960 :                     p_x[0][k][i] = L_shr( p_x[0][k][i], shr_k );
     337    45224960 :                     move32();
     338             :                 }
     339       59401 :                 shr_k = sub( 31 - Q11, p_x_e[1][k] );
     340    45284361 :                 FOR( Word16 i = 0; i < p_x_len[1][k]; i++ )
     341             :                 {
     342    45224960 :                     p_x[1][k][i] = L_shr( p_x[1][k][i], shr_k );
     343    45224960 :                     move32();
     344             :                 }
     345             :             }
     346             :             ELSE
     347             :             {
     348          60 :                 FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
     349             :                 {
     350             :                     Word16 x_e, x_len;
     351             : 
     352          40 :                     st = sts[ch];
     353          40 :                     test();
     354          40 :                     if ( bfi && ( st->core == ACELP_CORE ) ) /*no igf processing needed*/
     355             :                     {
     356           0 :                         CONTINUE;
     357             :                     }
     358          40 :                     tmp = BASOP_Util_Divide1616_Scale( st->hTcxCfg->tcx_coded_lines, nSubframes, &tmp_e );
     359          40 :                     L_spec[ch] = shr( tmp, add( 15, negate( tmp_e ) ) );
     360          40 :                     move32();
     361             : 
     362          40 :                     tmp = BASOP_Util_Divide1616_Scale( st->L_frame, nSubframes, &tmp_e );
     363          40 :                     L_frame_nSubframe = shr( tmp, add( 15, negate( tmp_e ) ) );
     364             : 
     365          40 :                     tmp = BASOP_Util_Divide1616_Scale( st->hTcxDec->L_frameTCX, nSubframes, &tmp_e );
     366          40 :                     L_frameTCX_nSubframe = shr( tmp, add( 15, negate( tmp_e ) ) );
     367             : 
     368          40 :                     init_tcx_info_fx( st, L_frame_nSubframe, L_frameTCX_nSubframe, k, bfi, &tcx_offset[ch], &tcx_offsetFB[ch], &L_frame[ch], &L_frameTCX[ch], &left_rect[ch], &L_spec[ch] );
     369             : 
     370             :                     /* mono or dual mono IGF decoding */
     371             : 
     372          40 :                     x_e = 31 - Q11; // input q-factor of x[p_ch[ch]][k] is Q12
     373          40 :                     move16();
     374             : 
     375          40 :                     decoder_tcx_IGF_mono_fx( st, x[p_ch[ch]][k], &x_e, &x_len, L_frame[ch], left_rect[ch], bfi, k );
     376             : 
     377       15720 :                     FOR( Word16 i = 0; i < x_len; i++ )
     378             :                     {
     379             :                         // Converting from variable exponent to Fixed q-factor (Q12)
     380       15680 :                         x[p_ch[ch]][k][i] = L_shr( x[p_ch[ch]][k][i], sub( 31 - Q11, x_e ) );
     381       15680 :                         move32();
     382             :                     }
     383             :                 }
     384             :             }
     385             :         }
     386             :     }
     387             : 
     388       33709 :     IF( sum16_fx( singleChEle, ( hMCT->nchan_out_woLFE ) ) != 0 )
     389             :     {
     390      195648 :         FOR( ch = 0; ch < ( hMCT->nchan_out_woLFE ); ch++ )
     391             :         {
     392      161943 :             IF( singleChEle[ch] )
     393             :             {
     394       46011 :                 st = stm[ch];
     395       46011 :                 test();
     396       46011 :                 if ( bfi && ( st->core == ACELP_CORE ) ) /*no igf processing needed*/
     397             :                 {
     398           0 :                     CONTINUE;
     399             :                 }
     400       46011 :                 if ( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
     401             :                 {
     402        1215 :                     CONTINUE;
     403             :                 }
     404             : 
     405       44796 :                 IF( EQ_16( st->core, TCX_10_CORE ) )
     406             :                 {
     407        1400 :                     nSubframes = NB_DIV;
     408             :                 }
     409             :                 ELSE
     410             :                 {
     411       43396 :                     nSubframes = 1;
     412             :                 }
     413       44796 :                 move16();
     414             : 
     415       90992 :                 FOR( k = 0; k < nSubframes; k++ )
     416             :                 {
     417             :                     Word16 x_e, x_len;
     418             : 
     419       46196 :                     tmp = BASOP_Util_Divide1616_Scale( st->hTcxCfg->tcx_coded_lines, nSubframes, &tmp_e );
     420       46196 :                     L_spec[0] = shr( tmp, add( 15, negate( tmp_e ) ) );
     421       46196 :                     move32();
     422             : 
     423       46196 :                     tmp = BASOP_Util_Divide1616_Scale( st->L_frame, nSubframes, &tmp_e );
     424       46196 :                     L_frame_nSubframe = shr( tmp, add( 15, negate( tmp_e ) ) );
     425             : 
     426       46196 :                     tmp = BASOP_Util_Divide1616_Scale( st->hTcxDec->L_frameTCX, nSubframes, &tmp_e );
     427       46196 :                     L_frameTCX_nSubframe = shr( tmp, add( 15, negate( tmp_e ) ) );
     428             : 
     429       46196 :                     init_tcx_info_fx( st, L_frame_nSubframe, L_frameTCX_nSubframe, k, bfi, &tcx_offset[0], &tcx_offsetFB[0], &L_frame[0], &L_frameTCX[0], &left_rect[0], &L_spec[0] );
     430             : 
     431             :                     /* mono or dual mono IGF decoding */
     432       46196 :                     x_e = 31 - Q11; // Input Q-factor is Q12.
     433       46196 :                     move16();
     434             : 
     435       46196 :                     decoder_tcx_IGF_mono_fx( st, x[ch][k], &x_e, &x_len, L_frame[0], left_rect[0], bfi, k );
     436             : 
     437    34858516 :                     FOR( Word16 i = 0; i < x_len; i++ )
     438             :                     {
     439             :                         // Converting from variable exponent to Fixed q-factor (Q12)
     440    34812320 :                         x[ch][k][i] = L_shr( x[ch][k][i], sub( 31 - Q11, x_e ) );
     441    34812320 :                         move32();
     442             :                     }
     443             :                 }
     444             :             }
     445             :         }
     446             :     }
     447             : 
     448       33709 :     return;
     449             : }

Generated by: LCOV version 1.14