LCOV - code coverage report
Current view: top level - lib_dec - ivas_sns_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 174 180 96.7 %
Date: 2025-05-03 01:55:50 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 "prot_fx.h"
      36             : #include "rom_com.h"
      37             : #include "ivas_rom_com.h"
      38             : #include "ivas_cnst.h"
      39             : #include <math.h>
      40             : #include "wmc_auto.h"
      41             : #include "ivas_rom_com_fx.h"
      42             : #include "ivas_prot_fx.h"
      43             : 
      44             : /*-------------------------------------------------------------------
      45             :  * sns_1st_dec_fx()
      46             :  *
      47             :  *
      48             :  *-------------------------------------------------------------------*/
      49             : 
      50      304877 : static void sns_1st_dec_fx(
      51             :     const Word16 index, /* i  : codebook index                  */
      52             :     const Word16 core,
      53             :     const Word16 L_frame,
      54             :     Word32 *snsq_fx /* i/o:  i:prediction   o:quantized sns Q16*/
      55             : )
      56             : {
      57             :     Word16 i;
      58             :     const Word16 *p_dico, *means;
      59             : 
      60      304877 :     const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15
      61      304877 :     move16();
      62      304877 :     const Word16 means_fix = 2; // 1.f / powf( 2, SNS_MEANS_BITS_4_FRAC ) in Q15
      63      304877 :     move16();
      64             : 
      65      304877 :     means = NULL;
      66      304877 :     SWITCH( L_frame )
      67             :     {
      68       31689 :         case L_FRAME16k:
      69       31689 :             means = &sns_1st_means_16k[core - 1][0]; /*Q0*/
      70       31689 :             BREAK;
      71       87088 :         case L_FRAME25_6k:
      72       87088 :             means = &sns_1st_means_25k6[core - 1][0]; /*Q0*/
      73       87088 :             BREAK;
      74      186100 :         case L_FRAME32k:
      75      186100 :             means = &sns_1st_means_32k[core - 1][0]; /*Q0*/
      76      186100 :             BREAK;
      77           0 :         default:
      78           0 :             assert( !"illegal frame length in sns_1st_cod" );
      79             :     }
      80             : 
      81             : 
      82      304877 :     p_dico = &sns_1st_cdbk[0][core - 1][0] + i_mult( index % 32, ( M / 2 ) ); /*Q0*/
      83             : 
      84     2743893 :     FOR( i = 0; i < M / 2; i++ )
      85             :     {
      86     2439016 :         snsq_fx[i] = L_add( L_mult( ( *p_dico++ ), cdbk_fix ), L_mult( means[i], means_fix ) ); // Q16
      87     2439016 :         move32();
      88             :     }
      89             : 
      90      304877 :     p_dico = &sns_1st_cdbk[1][sub( core, 1 )][0] + i_mult( shr( index, 5 ), ( M / 2 ) ); /*Q0*/
      91             : 
      92     2743893 :     FOR( i = M / 2; i < M; i++ )
      93             :     {
      94     2439016 :         snsq_fx[i] = L_add( L_mult( ( *p_dico++ ), cdbk_fix ), L_mult( means[i], means_fix ) ); /*Q16*/
      95     2439016 :         move32();
      96             :     }
      97             : 
      98      304877 :     return;
      99             : }
     100             : /*-------------------------------------------------------------------
     101             :  * sns_2st_dec_fx()
     102             :  *
     103             :  *
     104             :  *-------------------------------------------------------------------*/
     105             : 
     106      463831 : static void sns_2st_dec_fx(
     107             :     Word32 *snsq_fx, /* i/o: i:1st stage   o:1st+2nd stage   q_snsq*/
     108             :     Word16 *q_snsq,
     109             :     Word16 *indx /* i  : index[] (4 bits per words)      Q0*/
     110             : )
     111             : {
     112             :     Word16 i;
     113             :     Word16 xq_fx[M];
     114      463831 :     Word16 scale_fx = 13107; /*1.0/2.5f in Q15*/
     115      463831 :     move16();
     116             :     /* quantize */
     117      463831 :     AVQ_dec_lpc( indx, xq_fx, 2 );
     118      463831 :     Word32 tmp = 0;
     119      463831 :     move32();
     120      463831 :     Word16 snsq_dIFf = 0;
     121      463831 :     move16();
     122             :     Word32 tmp1;
     123             : 
     124     7885127 :     FOR( i = 0; i < M; i++ )
     125             :     {
     126     7421296 :         tmp = L_mult( scale_fx, xq_fx[i] ); // q16
     127     7421296 :         IF( GE_16( *q_snsq, 16 ) )
     128             :         {
     129     7421296 :             snsq_dIFf = sub( *q_snsq, 16 );
     130     7421296 :             tmp1 = L_shr( snsq_fx[i], snsq_dIFf ); /*Q16*/
     131     7421296 :             snsq_fx[i] = L_add( tmp1, tmp );       /*Q16*/
     132     7421296 :             move32();
     133     7421296 :             *q_snsq = 16;
     134     7421296 :             move16();
     135             :         }
     136             :         ELSE
     137             :         {
     138           0 :             snsq_dIFf = sub( 16, *q_snsq );
     139           0 :             tmp1 = L_shr( tmp, snsq_dIFf );         /*q_snsq*/
     140           0 :             snsq_fx[i] = L_add( snsq_fx[i], tmp1 ); /*q_snsq*/
     141           0 :             move32();
     142             :         }
     143             :     }
     144      463831 :     return;
     145             : }
     146             : /*-------------------------------------------------------------------
     147             :  * sns_avq_dec_fx()
     148             :  *
     149             :  * Stereo noise-shaping AVQ decoder FOR 1 channel
     150             :  *-------------------------------------------------------------------*/
     151             : 
     152       67056 : void sns_avq_dec_fx(
     153             :     Word16 *index,           /* i  : Quantization indices        Q0*/
     154             :     Word32 SNS_Q[NB_DIV][M], /* o  : Quantized SNS vectors       q_snsq*/
     155             :     Word16 *q_snsq,
     156             :     const Word16 L_frame, /* i  : frame length                Q0*/
     157             :     const Word16 numlpc   /* i  : Number of sets of lpc       Q0*/
     158             : )
     159             : {
     160             :     Word16 i, nbi, last;
     161             :     Word16 q_type;
     162             : 
     163             :     /* go from one-based indexing to zero-based indexing */
     164       67056 :     last = sub( numlpc, 1 ); /*Q0*/
     165             : 
     166       67056 :     index++;
     167             : 
     168             :     /* Decode last LPC */
     169       67056 :     sns_1st_dec_fx( *index++, numlpc, L_frame, SNS_Q[last] ); // Q16
     170       67056 :     *q_snsq = 16;
     171       67056 :     move16();
     172       67056 :     sns_2st_dec_fx( SNS_Q[last], q_snsq, index );
     173             : 
     174       67056 :     nbi = add( add( 2, index[0] ), index[1] ); /*Q0*/
     175       67056 :     index += nbi;
     176             : 
     177             :     /* Decode intermediate LPC (512 framing) */
     178       67056 :     IF( EQ_16( numlpc, 2 ) )
     179             :     {
     180       10469 :         q_type = *index++; /*Q0*/
     181       10469 :         move16();
     182             : 
     183       10469 :         IF( q_type == 0 )
     184             :         {
     185        3927 :             sns_1st_dec_fx( *index++, numlpc, L_frame, SNS_Q[0] );
     186        3927 :             *q_snsq = 16;
     187        3927 :             move16();
     188        3927 :             sns_2st_dec_fx( SNS_Q[0], q_snsq, index );
     189             :         }
     190        6542 :         ELSE IF( EQ_16( q_type, 1 ) )
     191             :         {
     192      111214 :             FOR( i = 0; i < M; i++ )
     193             :             {
     194      104672 :                 SNS_Q[0][i] = SNS_Q[1][i]; /*q_snsq*/
     195      104672 :                 move32();
     196             :             }
     197        6542 :             sns_2st_dec_fx( SNS_Q[0], q_snsq, index );
     198             :         }
     199             :     }
     200             : 
     201       67056 :     return;
     202             : }
     203             : 
     204             : /*-------------------------------------------------------------------
     205             :  * sns_avq_dec_stereo_fx()
     206             :  *
     207             :  * Stereo noise-shaping AVQ decoder FOR 21 channels
     208             :  *-------------------------------------------------------------------*/
     209             : 
     210      202475 : void sns_avq_dec_stereo_fx(
     211             :     Word16 *indexl,       /* i  : Quantization indices (left channel)     Q0*/
     212             :     Word16 *indexr,       /* i  : Quantization indices (right channe)     Q0*/
     213             :     const Word16 L_frame, /* i  : frame length                            Q0*/
     214             :     Word32 *SNS_Ql,       /* o  : Quantized SNS vectors (left channel)    q_l*/
     215             :     Word16 *q_l,
     216             :     Word32 *SNS_Qr, /* o  : Quantized SNS vectors (right channe)    q_r*/
     217             :     Word16 *q_r )
     218             : {
     219             :     Word16 i, stereo_mode;
     220             : 
     221             :     Word32 mid_q_fx[M], side_q_fx[M];
     222      202475 :     stereo_mode = *indexl++; /*Q0*/
     223      202475 :     move16();
     224             : 
     225      202475 :     indexr++;
     226      202475 :     Word16 tmp1 = 0, tmp2 = 0, q_mid = 0, q_side = 0;
     227      202475 :     Word16 tmp_dIFf_q = 0;
     228      202475 :     move16();
     229      202475 :     move16();
     230      202475 :     move16();
     231      202475 :     move16();
     232      202475 :     move16();
     233             : 
     234      202475 :     IF( EQ_16( stereo_mode, 2 ) )
     235             :     {
     236             :         /* MS coding */
     237      171056 :         tmp1 = *indexl++; /*Q0*/
     238      171056 :         move16();
     239      171056 :         sns_1st_dec_fx( tmp1, TCX_20_CORE, L_frame, mid_q_fx );
     240      171056 :         q_mid = 16;
     241      171056 :         move16();
     242      171056 :         sns_2st_dec_fx( mid_q_fx, &q_mid, indexl );
     243             : 
     244     2907952 :         FOR( i = 0; i < M; i++ )
     245             :         {
     246     2736896 :             side_q_fx[i] = 0;
     247     2736896 :             move32();
     248     2736896 :             q_side = 31;
     249     2736896 :             move16();
     250             :         }
     251             : 
     252      171056 :         IF( EQ_16( *indexr++, -1 ) )
     253             :         {
     254      152412 :             sns_2st_dec_fx( side_q_fx, &q_side, indexr );
     255             :         }
     256             : 
     257      171056 :         Word32 tmp_c = 0;
     258      171056 :         move32();
     259     2907952 :         FOR( i = 0; i < M; i++ )
     260             :         {
     261     2736896 :             tmp_c = L_shr( side_q_fx[i], 1 ); // q_side
     262             : 
     263     2736896 :             IF( GE_16( q_mid, q_side ) )
     264             :             {
     265     2438592 :                 tmp_dIFf_q = sub( q_mid, q_side );
     266     2438592 :                 SNS_Ql[i] = L_add( L_shr( mid_q_fx[i], tmp_dIFf_q ), tmp_c ); // q_side
     267     2438592 :                 move32();
     268     2438592 :                 SNS_Qr[i] = L_sub( L_shr( mid_q_fx[i], tmp_dIFf_q ), tmp_c ); // q_side
     269     2438592 :                 move32();
     270     2438592 :                 *q_r = q_side;
     271     2438592 :                 move16();
     272     2438592 :                 *q_l = *q_r;
     273     2438592 :                 move16();
     274             :             }
     275             :             ELSE
     276             :             {
     277      298304 :                 tmp_dIFf_q = sub( q_side, q_mid );
     278      298304 :                 SNS_Ql[i] = L_add( mid_q_fx[i], L_shr( tmp_c, tmp_dIFf_q ) ); // q_mid
     279      298304 :                 move32();
     280      298304 :                 SNS_Qr[i] = L_sub( mid_q_fx[i], L_shr( tmp_c, tmp_dIFf_q ) ); // q_mid
     281      298304 :                 move32();
     282      298304 :                 *q_r = q_mid;
     283      298304 :                 move16();
     284      298304 :                 *q_l = *q_r;
     285      298304 :                 move16();
     286             :             }
     287             :         }
     288             :     }
     289             :     ELSE
     290             :     {
     291             :         /* LR decoding */
     292       31419 :         tmp1 = *indexl++; /*Q0*/
     293       31419 :         move16();
     294       31419 :         tmp2 = *indexr++; /*Q0*/
     295       31419 :         move16();
     296       31419 :         sns_1st_dec_fx( tmp1, TCX_20_CORE, L_frame, SNS_Ql );
     297       31419 :         *q_l = 16;
     298       31419 :         move16();
     299       31419 :         sns_2st_dec_fx( SNS_Ql, q_l, indexl );
     300             : 
     301       31419 :         sns_1st_dec_fx( tmp2, TCX_20_CORE, L_frame, SNS_Qr );
     302       31419 :         *q_r = 16;
     303       31419 :         move16();
     304       31419 :         sns_2st_dec_fx( SNS_Qr, q_r, indexr );
     305             :     }
     306             : 
     307      202475 :     return;
     308             : }
     309             : 
     310             : /*-------------------------------------------------------------------
     311             :  * dequantize_sns_fx()
     312             :  *
     313             :  * Dequantize SNS
     314             :  *-------------------------------------------------------------------*/
     315             : 
     316       44418 : void dequantize_sns_fx(
     317             :     Word16 indices[CPE_CHANNELS][NPRM_LPC_NEW],  /*Q0*/
     318             :     Word32 snsQ_out_fx[CPE_CHANNELS][NB_DIV][M], /*Q16*/
     319             :     Decoder_State **sts )
     320             : {
     321             :     Word16 nSubframes, k, ch;
     322             :     Word16 sns_stereo_mode[NB_DIV];
     323             :     Word16 zero_side_flag[NB_DIV];
     324             :     Decoder_State *st;
     325             : 
     326       44418 :     sns_stereo_mode[0] = indices[0][0]; /*Q0*/
     327       44418 :     move16();
     328       44418 :     sns_stereo_mode[1] = indices[0][1]; /*Q0*/
     329       44418 :     move16();
     330       44418 :     zero_side_flag[0] = indices[0][2]; /*Q0*/
     331       44418 :     move16();
     332       44418 :     zero_side_flag[1] = indices[0][3]; /*Q0*/
     333       44418 :     move16();
     334             : 
     335      133254 :     FOR( ch = 0; ch < CPE_CHANNELS; ++ch )
     336             :     {
     337             :         Word16 idxIndices;
     338             : 
     339       88836 :         st = sts[ch];
     340       88836 :         nSubframes = NB_DIV;
     341       88836 :         move16();
     342       88836 :         if ( EQ_16( st->core, TCX_20_CORE ) )
     343             :         {
     344       86628 :             nSubframes = 1;
     345       86628 :             move16();
     346             :         }
     347             : 
     348       88836 :         idxIndices = 0;
     349       88836 :         move16();
     350             : 
     351      179880 :         FOR( k = 0; k < nSubframes; ++k )
     352             :         {
     353       91044 :             const Word16 is_side = EQ_16( ch, 1 ) && EQ_16( sns_stereo_mode[k], SNS_STEREO_MODE_MS );
     354             : 
     355       91044 :             const Word16 *const *cdbks_fx = EQ_16( nSubframes, 1 ) ? ivas_sns_cdbks_tcx20_fx : ivas_sns_cdbks_tcx10_fx;
     356             : 
     357       91044 :             Word16 nStages = SNS_MSVQ_NSTAGES_TCX10;
     358       91044 :             move16();
     359             : 
     360       91044 :             if ( EQ_16( nSubframes, 1 ) )
     361             :             {
     362       86628 :                 nStages = SNS_MSVQ_NSTAGES_TCX20;
     363       86628 :                 move16();
     364             :             }
     365             : 
     366       91044 :             Word32 *snsQ_fx = snsQ_out_fx[ch][k]; /*Q16*/
     367             : 
     368       91044 :             IF( is_side )
     369             :             {
     370       42035 :                 const Word16 *const *side_cdbks_fx = EQ_16( st->core, TCX_20_CORE ) ? ivas_sns_cdbks_side_tcx20_fx : ivas_sns_cdbks_side_tcx10_fx;
     371             : 
     372       42035 :                 IF( zero_side_flag[k] )
     373             :                 {
     374        8675 :                     set32_fx( snsQ_fx, 0, M );
     375        8675 :                     CONTINUE;
     376             :                 }
     377             : 
     378       33360 :                 nStages = SNS_MSVQ_NSTAGES_SIDE;
     379       33360 :                 move16();
     380       33360 :                 msvq_dec_fx( side_cdbks_fx, NULL, NULL, nStages, M, M, &indices[ch][( idxIndices + SNS_STEREO_MODE_OFFSET_INDICES )], 0, NULL, snsQ_fx, NULL, 15 ); // always 15
     381             :             }
     382             :             ELSE
     383             :             {
     384       49009 :                 msvq_dec_fx( cdbks_fx, NULL, NULL, nStages, M, M, &indices[ch][( idxIndices + SNS_STEREO_MODE_OFFSET_INDICES )], 0, NULL, snsQ_fx, NULL, 12 );
     385             :             }
     386       82369 :             idxIndices = add( idxIndices, nStages ); /*Q0*/
     387             :         }
     388             :     }
     389             : 
     390       44418 :     IF( EQ_16( sns_stereo_mode[0], SNS_STEREO_MODE_MS ) || EQ_16( sns_stereo_mode[1], SNS_STEREO_MODE_MS ) )
     391             :     {
     392       41221 :         nSubframes = NB_DIV;
     393       41221 :         move16();
     394       41221 :         if ( EQ_16( sts[0]->core, TCX_20_CORE ) )
     395             :         {
     396       40315 :             nSubframes = 1;
     397       40315 :             move16();
     398             :         }
     399       83348 :         FOR( k = 0; k < nSubframes; ++k )
     400             :         {
     401       42127 :             IF( EQ_16( sns_stereo_mode[k], SNS_STEREO_MODE_MS ) )
     402             :             {
     403       42035 :                 inverseMS_fx( M, snsQ_out_fx[0][k], snsQ_out_fx[1][k], ONE_IN_Q31 ); /*Q16*/
     404             :             }
     405             :         }
     406             :     }
     407             : 
     408       44418 :     return;
     409             : }

Generated by: LCOV version 1.14