LCOV - code coverage report
Current view: top level - lib_enc - enc_higher_acelp.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 99 102 97.1 %
Date: 2025-05-23 08:37:30 Functions: 3 3 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             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include <stdint.h>
      38             : #include "options.h"
      39             : #ifdef DEBUGGING
      40             : #include "debug.h"
      41             : #endif
      42             : #include <math.h>
      43             : #include "cnst.h"
      44             : #include "prot.h"
      45             : #include "rom_com.h"
      46             : #include "wmc_auto.h"
      47             : 
      48             : /*---------------------------------------------------------------------*
      49             :  * Local function prototypes
      50             :  *---------------------------------------------------------------------*/
      51             : 
      52             : static void find_cn( const float xn[], const float Ap[], const float *p_Aq, float cn[] );
      53             : 
      54             : 
      55             : /*-----------------------------------------------------------------*
      56             :  * transf_cdbk_enc()
      57             :  *
      58             :  * Transform domain contribution encoding
      59             :  *-----------------------------------------------------------------*/
      60             : 
      61       73935 : void transf_cdbk_enc(
      62             :     Encoder_State *st,             /* i/o: encoder state structure                         */
      63             :     const int16_t harm_flag_acelp, /* i  : harmonic flag for higher rates ACELP            */
      64             :     const int16_t i_subfr,         /* i  : subframe index                                  */
      65             :     float cn[],                    /* i/o: target vector in residual domain                */
      66             :     float exc[],                   /* i/o: pointer to excitation signal frame              */
      67             :     const float *p_Aq,             /* i  : 12k8 Lp coefficient                             */
      68             :     const float Ap[],              /* i  : weighted LP filter coefficients                 */
      69             :     const float h1[],              /* i  : weighted filter input response                  */
      70             :     float xn[],                    /* i/o: target vector                                   */
      71             :     float xn2[],                   /* i/o: target vector for innovation search             */
      72             :     float y1[],                    /* i/o: zero-memory filtered adaptive excitation        */
      73             :     const float y2[],              /* i  : zero-memory filtered innovative excitation      */
      74             :     const float Es_pred,           /* i  : predicited scaled innovation energy             */
      75             :     float *gain_pit,               /* i/o: adaptive excitation gain                        */
      76             :     const float gain_code,         /* i  : innovative excitation gain                      */
      77             :     float g_corr[],                /* o  : ACELP correlation values                        */
      78             :     const int16_t clip_gain,       /* i  : adaptive gain clipping flag                     */
      79             :     float *gain_preQ,              /* o  : prequantizer excitation gain                    */
      80             :     float code_preQ[],             /* o  : prequantizer excitation                         */
      81             :     int16_t *unbits                /* o  : number of AVQ unused bits                       */
      82             : )
      83             : {
      84             :     int16_t i, index, nBits, Nsv;
      85             :     float x_in[L_SUBFR], x_tran[L_SUBFR], temp;
      86             :     int16_t x_norm[L_SUBFR + L_SUBFR / WIDTH_BAND];
      87             :     float corr, ener;
      88             :     int16_t nq[L_SUBFR / WIDTH_BAND];
      89             :     int16_t avq_bit_sFlag;
      90             :     int16_t trgtSvPos;
      91             : 
      92       73935 :     avq_bit_sFlag = 0;
      93       73935 :     if ( st->element_mode > EVS_MONO )
      94             :     {
      95       70590 :         avq_bit_sFlag = 1;
      96             :     }
      97             : 
      98             :     /*--------------------------------------------------------------*
      99             :      * Set bit-allocation
     100             :      *--------------------------------------------------------------*/
     101             : 
     102       73935 :     Nsv = 8;
     103       73935 :     nBits = st->acelp_cfg.AVQ_cdk_bits[i_subfr / L_SUBFR];
     104             : 
     105             :     /* increase # of AVQ allocated bits by unused bits from the previous subframe */
     106       73935 :     nBits += ( *unbits );
     107             : 
     108             :     /*--------------------------------------------------------------*
     109             :      * Compute/Update target
     110             :      * For inactive frame, find target in residual domain
     111             :      * Deemphasis
     112             :      *--------------------------------------------------------------*/
     113             : 
     114       73935 :     if ( st->coder_type == INACTIVE )
     115             :     {
     116      846950 :         for ( i = 0; i < L_SUBFR; i++ )
     117             :         {
     118      833920 :             x_tran[i] = xn[i] - *gain_pit * y1[i] - gain_code * y2[i];
     119             :         }
     120             : 
     121       13030 :         find_cn( x_tran, Ap, p_Aq, x_in );
     122             :     }
     123             :     else
     124             :     {
     125       60905 :         updt_tar( cn, x_in, &exc[i_subfr], *gain_pit, L_SUBFR );
     126             :     }
     127             : 
     128       73935 :     deemph( x_in, FAC_PRE_AVQ, L_SUBFR, &st->mem_deemp_preQ );
     129             : 
     130             :     /*--------------------------------------------------------------*
     131             :      * DCT-II
     132             :      *--------------------------------------------------------------*/
     133             : 
     134       73935 :     if ( st->coder_type != INACTIVE && st->core_brate >= MIN_BRATE_AVQ_EXC && st->core_brate <= MAX_BRATE_AVQ_EXC_TD && !harm_flag_acelp )
     135             :     {
     136       41400 :         mvr2r( x_in, x_tran, L_SUBFR );
     137             :     }
     138             :     else
     139             :     {
     140       32535 :         edct2( L_SUBFR, -1, x_in, x_tran, ip_edct2_64, w_edct2_64 );
     141             :     }
     142             : 
     143             :     /*--------------------------------------------------------------*
     144             :      * Split algebraic vector quantizer based on RE8 lattice
     145             :      *--------------------------------------------------------------*/
     146             : 
     147       73935 :     AVQ_cod( x_tran, x_norm, nBits, Nsv );
     148             : 
     149             :     /*--------------------------------------------------------------*
     150             :      * Find prequantizer excitation gain
     151             :      * Quantize the gain
     152             :      *--------------------------------------------------------------*/
     153             : 
     154       73935 :     corr = 0;
     155       73935 :     ener = 1e-6f;
     156             : 
     157     4805775 :     for ( i = 0; i < Nsv * 8; i++ )
     158             :     {
     159     4731840 :         corr += x_tran[i] * (float) x_norm[i];
     160     4731840 :         ener += (float) x_norm[i] * (float) x_norm[i];
     161             :     }
     162             : 
     163       73935 :     *gain_preQ = corr / ener;
     164             : 
     165       73935 :     if ( st->coder_type == INACTIVE )
     166             :     {
     167       13030 :         *gain_preQ /= gain_code;
     168             : 
     169       13030 :         if ( st->core_brate > 56000 )
     170             :         {
     171           0 :             index = usquant( *gain_preQ, gain_preQ, G_AVQ_MIN_INACT_64k, G_AVQ_DELTA_INACT_64k, ( 1 << G_AVQ_BITS ) );
     172             :         }
     173       13030 :         else if ( st->core_brate > 42000 )
     174             :         {
     175        1575 :             index = usquant( *gain_preQ, gain_preQ, G_AVQ_MIN_INACT_48k, G_AVQ_DELTA_INACT_48k, ( 1 << G_AVQ_BITS ) );
     176             :         }
     177             :         else
     178             :         {
     179       11455 :             index = usquant( *gain_preQ, gain_preQ, G_AVQ_MIN_INACT, G_AVQ_DELTA_INACT, ( 1 << G_AVQ_BITS ) );
     180             :         }
     181             : 
     182       13030 :         *gain_preQ *= gain_code;
     183             :     }
     184             :     else
     185             :     {
     186       60905 :         if ( Es_pred < 0 )
     187             :         {
     188         360 :             temp = (float) ( 0.25f * fabs( Es_pred ) );
     189             :         }
     190             :         else
     191             :         {
     192       60545 :             temp = Es_pred;
     193             :         }
     194       60905 :         *gain_preQ /= temp;
     195             : 
     196       60905 :         if ( st->core_brate > ACELP_24k40 && st->core_brate <= 42000 )
     197             :         {
     198       51930 :             index = gain_quant( gain_preQ, 0.1f * G_AVQ_MIN, G_AVQ_MAX, G_AVQ_BITS );
     199             :         }
     200             :         else
     201             :         {
     202        8975 :             index = gain_quant( gain_preQ, G_AVQ_MIN, G_AVQ_MAX, G_AVQ_BITS );
     203             :         }
     204       60905 :         *gain_preQ *= temp;
     205             :     }
     206             : 
     207       73935 :     push_indice( st->hBstr, IND_AVQ_GAIN, index, G_AVQ_BITS );
     208             : 
     209             :     /*--------------------------------------------------------------*
     210             :      * Encode and multiplex subvectors into bitstream
     211             :      *--------------------------------------------------------------*/
     212             : 
     213       73935 :     trgtSvPos = Nsv - 1;
     214       73935 :     if ( avq_bit_sFlag && nBits > 85 && !harm_flag_acelp && ( st->coder_type == GENERIC || st->coder_type == TRANSITION || st->coder_type == INACTIVE ) )
     215             :     {
     216       20139 :         trgtSvPos = 2;
     217       20139 :         avq_bit_sFlag = 2;
     218             :     }
     219             : 
     220       73935 :     AVQ_encmux( st->hBstr, -1, x_norm, &nBits, Nsv, nq, avq_bit_sFlag, trgtSvPos );
     221             : 
     222             :     /* save # of AVQ unused bits for next subframe */
     223       73935 :     *unbits = nBits;
     224             : 
     225             :     /* at the last subframe, write AVQ unused bits */
     226       73935 :     if ( i_subfr == 4 * L_SUBFR && st->extl != SWB_BWE_HIGHRATE && st->extl != FB_BWE_HIGHRATE )
     227             :     {
     228       26490 :         while ( *unbits > 0 )
     229             :         {
     230       12372 :             i = min( *unbits, 16 );
     231       12372 :             push_indice( st->hBstr, IND_UNUSED, 0, i );
     232       12372 :             *unbits -= i;
     233             :         }
     234             :     }
     235             : 
     236             :     /*--------------------------------------------------------------*
     237             :      * DCT transform
     238             :      *--------------------------------------------------------------*/
     239             : 
     240     4805775 :     for ( i = 0; i < Nsv * WIDTH_BAND; i++ )
     241             :     {
     242     4731840 :         x_tran[i] = (float) ( x_norm[i] );
     243             :     }
     244             : 
     245       73935 :     if ( st->coder_type != INACTIVE && st->core_brate >= MIN_BRATE_AVQ_EXC && st->core_brate <= MAX_BRATE_AVQ_EXC_TD && !harm_flag_acelp )
     246             :     {
     247       41400 :         mvr2r( x_tran, code_preQ, L_SUBFR );
     248             :     }
     249             :     else
     250             :     {
     251       32535 :         edct2( L_SUBFR, 1, x_tran, code_preQ, ip_edct2_64, w_edct2_64 );
     252             :     }
     253             : 
     254             :     /*--------------------------------------------------------------*
     255             :      * Preemphasise
     256             :      *--------------------------------------------------------------*/
     257             : 
     258             :     /* in extreme cases at subframe boundaries, lower the preemphasis memory to avoid a saturation */
     259       73935 :     if ( ( nq[7] != 0 ) && ( st->last_nq_preQ - nq[0] > 7 ) )
     260             :     {
     261           0 :         st->mem_preemp_preQ /= 16;
     262             :     }
     263             : 
     264       73935 :     st->last_nq_preQ = nq[7];
     265             : 
     266             :     /* TD pre-quantizer: in extreme cases at subframe boundaries, lower the preemphasis memory to avoid a saturation */
     267       73935 :     if ( st->element_mode > EVS_MONO && st->coder_type != INACTIVE && st->core_brate >= MIN_BRATE_AVQ_EXC && st->core_brate <= MAX_BRATE_AVQ_EXC_TD && !harm_flag_acelp && code_preQ[0] != 0 )
     268             :     {
     269       18052 :         if ( (float) abs( st->last_code_preq ) > 16.0f * (float) fabs( code_preQ[0] ) )
     270             :         {
     271           0 :             st->mem_preemp_preQ /= 16;
     272             :         }
     273       18052 :         else if ( (float) abs( st->last_code_preq ) > 8.0f * (float) fabs( code_preQ[0] ) )
     274             :         {
     275           4 :             st->mem_preemp_preQ /= 8;
     276             :         }
     277             :     }
     278             : 
     279       73935 :     st->last_code_preq = (int16_t) code_preQ[L_SUBFR - 1];
     280             : 
     281       73935 :     preemph( code_preQ, FAC_PRE_AVQ, L_SUBFR, &st->mem_preemp_preQ );
     282             : 
     283             :     /*--------------------------------------------------------------*
     284             :      * For inactive segments
     285             :      * - Zero-memory filtered pre-filter excitation
     286             :      * - Update of targets and gain_pit
     287             :      * For active segments
     288             :      * - Update xn[L_subfr-1] for updating the memory of the weighting filter
     289             :      *--------------------------------------------------------------*/
     290             : 
     291       73935 :     if ( st->coder_type == INACTIVE )
     292             :     {
     293       13030 :         temp = code_preQ[0] * h1[L_SUBFR - 1];
     294             : 
     295      833920 :         for ( i = 1; i < L_SUBFR; i++ )
     296             :         {
     297      820890 :             temp += code_preQ[i] * h1[L_SUBFR - 1 - i];
     298             :         }
     299             : 
     300       13030 :         xn[L_SUBFR - 1] -= *gain_preQ * temp;
     301             :     }
     302             :     else
     303             :     {
     304       60905 :         conv( code_preQ, h1, x_tran, L_SUBFR );
     305             : 
     306       60905 :         updt_tar( cn, cn, code_preQ, *gain_preQ, L_SUBFR );
     307       60905 :         updt_tar( xn, xn, x_tran, *gain_preQ, L_SUBFR );
     308             : 
     309       60905 :         *gain_pit = corr_xy1( xn, y1, g_corr, L_SUBFR, 0 );
     310             : 
     311             :         /* clip gain if necessary to avoid problems at decoder */
     312       60905 :         if ( clip_gain == 1 && *gain_pit > 0.95f )
     313             :         {
     314          86 :             *gain_pit = 0.95f;
     315             :         }
     316             : 
     317       60905 :         updt_tar( xn, xn2, y1, *gain_pit, L_SUBFR );
     318             :     }
     319             : 
     320       73935 :     st->use_acelp_preq = 1;
     321             : 
     322       73935 :     return;
     323             : }
     324             : 
     325             : /*-------------------------------------------------------------------*
     326             :  * Find target in residual domain - cn[]
     327             :  *-------------------------------------------------------------------*/
     328             : 
     329       13030 : static void find_cn(
     330             :     const float xn[],  /* i  : target signal                                   */
     331             :     const float Ap[],  /* i  : weighted LP filter coefficients                 */
     332             :     const float *p_Aq, /* i  : 12k8 LP coefficients                            */
     333             :     float cn[]         /* o  : target signal in residual domain                */
     334             : )
     335             : {
     336             :     float tmp, tmp_fl[L_SUBFR + M];
     337             : 
     338       13030 :     set_f( tmp_fl, 0, M );
     339       13030 :     mvr2r( xn, tmp_fl + M, L_SUBFR );
     340       13030 :     tmp = 0.0f;
     341             : 
     342       13030 :     preemph( tmp_fl + M, PREEMPH_FAC_16k, L_SUBFR, &tmp );
     343       13030 :     syn_filt( Ap, M, tmp_fl + M, tmp_fl + M, L_SUBFR, tmp_fl, 0 );
     344       13030 :     residu( p_Aq, M, tmp_fl + M, cn, L_SUBFR );
     345             : 
     346       13030 :     return;
     347             : }
     348             : 
     349             : /*---------------------------------------------------------------*
     350             :  * gain_quant()
     351             :  *
     352             :  * Quantization of gains between the specified range
     353             :  * using the specified number of levels.
     354             :  *---------------------------------------------------------------*/
     355             : 
     356             : /*! r: quantization index */
     357      113980 : int16_t gain_quant(
     358             :     float *gain,         /* i/o: quantized gain                */
     359             :     const float min_val, /* i  : value of lower limit          */
     360             :     const float max_val, /* i  : value of upper limit          */
     361             :     const int16_t bits   /* i  : number of bits to quantize    */
     362             : )
     363             : {
     364             :     int16_t index, levels;
     365             :     float tmp, c_min, c_mult;
     366             : 
     367      113980 :     levels = 1 << bits;
     368             : 
     369      113980 :     if ( *gain < FLT_MIN )
     370             :     {
     371         979 :         *gain = FLT_MIN;
     372             :     }
     373             : 
     374      113980 :     c_min = (float) log10( min_val );
     375      113980 :     c_mult = (float) ( ( levels - 1 ) / ( log10( max_val ) - c_min ) );
     376             : 
     377      113980 :     tmp = c_mult * ( (float) log10( *gain ) - c_min );
     378      113980 :     index = (int16_t) ( tmp + 0.5f );
     379             : 
     380      113980 :     if ( index < 0 )
     381             :     {
     382        1643 :         index = 0;
     383             :     }
     384      113980 :     if ( index > levels - 1 )
     385             :     {
     386         177 :         index = levels - 1;
     387             :     }
     388             : 
     389      113980 :     *gain = (float) pow( 10.0, ( ( (float) index ) / c_mult ) + c_min );
     390             : 
     391      113980 :     return ( index );
     392             : }

Generated by: LCOV version 1.14