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

Generated by: LCOV version 1.14