LCOV - code coverage report
Current view: top level - lib_enc - q_gain2p.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 75 104 72.1 %
Date: 2025-05-23 08:37:30 Functions: 3 4 75.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 "prot.h"
      44             : #include "cnst.h"
      45             : #include "rom_com.h"
      46             : #include "wmc_auto.h"
      47             : 
      48             : /*-------------------------------------------------------------------------*
      49             :  * Local function prototypes
      50             :  *-------------------------------------------------------------------------*/
      51             : 
      52             : static int16_t gain_enc_uv( const float *code, const int16_t lcode, float *gain_pit, float *gain_code, ACELP_CbkCorr *coeff, float *past_gcode, float *gain_inov );
      53             : 
      54             : 
      55             : /*-------------------------------------------------------------------------*
      56             :  * procedure q_gain2_plus                                                  *
      57             :  * ~~~~~~~~~~~~~~~~~~~~~~                                                  *
      58             :  * Quantization of pitch and codebook gains.                               *
      59             :  * The following routines is Q_gains updated for AMR_WB_PLUS.              *
      60             :  * MA prediction is removed and MEAN_ENER is now quantized with 2 bits and *
      61             :  * transmitted once every ACELP frame to the gains decoder.                *
      62             :  * The pitch gain and the code gain are vector quantized and the           *
      63             :  * mean-squared weighted error criterion is used in the quantizer search.  *
      64             :  *-------------------------------------------------------------------------*/
      65             : 
      66        3020 : void encode_acelp_gains(
      67             :     const float *code,
      68             :     const int16_t gains_mode,
      69             :     const float mean_ener_code,
      70             :     const int16_t clip_gain,
      71             :     ACELP_CbkCorr *g_corr,
      72             :     float *gain_pit,
      73             :     float *gain_code,
      74             :     int16_t **pt_indice,
      75             :     float *past_gcode,
      76             :     float *gain_inov,
      77             :     const int16_t L_subfr,
      78             :     float *code2,
      79             :     float *gain_code2,
      80             :     const int16_t noisy_speech_flag )
      81             : {
      82        3020 :     int16_t index = 0;
      83             : 
      84        3020 :     if ( ( ( gains_mode > 0 ) && ( gains_mode < 4 ) ) )
      85             :     {
      86             :         /* Memory-less gain coding */
      87        3020 :         index = Mode2_gain_enc_mless( code, L_subfr, gain_pit, gain_code, g_corr, mean_ener_code, clip_gain, past_gcode, gain_inov, gains_mode - 1 );
      88             :     }
      89           0 :     else if ( gains_mode == 6 )
      90             :     {
      91             :         /* UV gains quantizer (6bits/subfr) */
      92           0 :         index = gain_enc_uv( code, L_subfr, gain_pit, gain_code, g_corr, past_gcode, gain_inov );
      93             :     }
      94           0 :     else if ( gains_mode == 7 )
      95             :     {
      96             :         /* GACELP_UV gains quantizer (7=5-2bits/subfr) */
      97           0 :         index = gain_enc_gacelp_uv( code, code2, L_subfr, mean_ener_code, gain_pit, gain_code, gain_code2, g_corr, past_gcode, gain_inov, noisy_speech_flag );
      98             :     }
      99             :     else
     100             :     {
     101           0 :         IVAS_ERROR( IVAS_ERR_INTERNAL, "invalid gains coding for acelp!" );
     102             :     }
     103             : 
     104        3020 :     **pt_indice = index;
     105        3020 :     ( *pt_indice )++;
     106             : 
     107        3020 :     return;
     108             : }
     109             : 
     110             : /*---------------------------------------------------------------------*
     111             :  * procedure Mode2_gain_enc_mless
     112             :  * Quantization of pitch and codebook gains.
     113             :  * - an initial predicted gain, gcode0, is first determined based on
     114             :  *   the predicted scaled innovation energy
     115             :  * - the correction  factor gamma = g_code / gcode0 is then vector quantized
     116             :  *   along with gain_pit
     117             :  * - the mean-squared weighted error criterion is used for the quantizer search
     118             :  *---------------------------------------------------------------------*/
     119             : 
     120        3020 : int16_t Mode2_gain_enc_mless(
     121             :     const float *code,       /* i  : algebraic excitation                                            */
     122             :     const int16_t lcode,     /* i  : Subframe size                                                   */
     123             :     float *gain_pit,         /* o  : quantized pitch gain                                            */
     124             :     float *gain_code,        /* o  : quantized codebook gain                                         */
     125             :     ACELP_CbkCorr *pcoeff,   /* i/o: correlations <y1,y1>, -2<xn,y 1>,<y2,y2>, -2<xn,y2> and 2<y1,y2>*/
     126             :     const float mean_ener,   /* i  : mean_ener defined in open-loop (3 bits)                         */
     127             :     const int16_t clip_gain, /* i  : gain pitch clipping flag (1 = clipping)                         */
     128             :     float *past_gcode,       /* i/o: past gain of code                                               */
     129             :     float *gain_inov,        /* o  : unscaled innovation gain                                        */
     130             :     const int16_t coder_type /* i  : coder type                                                      */
     131             : )
     132             : {
     133             :     int16_t index, i, size, size_clip;
     134             :     const Word16 *p, *t_qua_gain;
     135             :     float dist, dist_min, g_pitch, g_code, gcode0, ener_code;
     136             :     ACELP_CbkCorr coeff;
     137             : 
     138             :     /*-----------------------------------------------------------------*
     139             :      * - calculate the unscaled innovation energy
     140             :      * - calculate the predicted gain code
     141             :      *-----------------------------------------------------------------*/
     142             : 
     143        3020 :     if ( coder_type == 0 )
     144             :     {
     145           0 :         *gain_inov = 1.0f / (float) sqrt( ( dotp( code, code, lcode ) + 0.01f ) / lcode );
     146           0 :         ener_code = 10 * (float) log10( ( dotp( code, code, lcode ) + 0.01f ) / lcode );
     147           0 :         gcode0 = (float) pow( 10, 0.05 * ( mean_ener - ener_code ) );
     148             :     }
     149             :     else
     150             :     {
     151        3020 :         ener_code = 0.01F;
     152      196300 :         for ( i = 0; i < lcode; i++ )
     153             :         {
     154      193280 :             ener_code += code[i] * code[i];
     155             :         }
     156             : 
     157        3020 :         *gain_inov = (float) sqrt( (float) lcode / ener_code );
     158             : 
     159        3020 :         ener_code = (float) ( -10.0 * log10( (float) lcode / ener_code ) );
     160        3020 :         gcode0 = mean_ener - ener_code;
     161        3020 :         gcode0 = (float) pow( 10.0, gcode0 / 20.0 ); /* predicted gain */
     162             :     }
     163             : 
     164             :     /*-----------------------------------------------------------------*
     165             :      * gain quantization initializations
     166             :      * - find the initial quantization pitch index
     167             :      * - set the gains searching range
     168             :      *-----------------------------------------------------------------*/
     169             : 
     170        3020 :     if ( coder_type == 0 )
     171             :     {
     172           0 :         t_qua_gain = E_ROM_qua_gain5b_const;
     173           0 :         size_clip = 9;
     174           0 :         size = NB_QUA_GAIN5B;
     175             :     }
     176        3020 :     else if ( coder_type == 1 )
     177             :     {
     178         130 :         t_qua_gain = E_ROM_qua_gain6b_const;
     179         130 :         size_clip = 6;
     180         130 :         size = NB_QUA_GAIN6B; /* searching range of the gain quantizer */
     181             :     }
     182             :     else
     183             :     {
     184        2890 :         t_qua_gain = E_ROM_qua_gain7b_const;
     185        2890 :         size_clip = 21;
     186        2890 :         size = NB_QUA_GAIN7B;
     187             :     }
     188             : 
     189        3020 :     if ( clip_gain == 1 )
     190             :     {
     191           0 :         size -= size_clip; /* limit pitch gain  to 1.0 */
     192             :     }
     193             : 
     194        3020 :     coeff = *pcoeff;
     195        3020 :     coeff.xy1 *= -2.0f;
     196        3020 :     coeff.xy2 *= -2.0f;
     197        3020 :     coeff.y1y2 *= 2.0f;
     198             : 
     199             :     /*-----------------------------------------------------------------*
     200             :      * search for the best quantizer
     201             :      *-----------------------------------------------------------------*/
     202             : 
     203        3020 :     p = t_qua_gain;
     204        3020 :     dist_min = FLT_MAX;
     205        3020 :     index = 0;
     206             : 
     207      381260 :     for ( i = 0; i < size; i++ )
     208             :     {
     209      378240 :         g_pitch = (float) ( *p++ ) / ( 1 << 14 );         /* pitch gain */
     210      378240 :         g_code = gcode0 * (float) ( *p++ ) / ( 1 << 11 ); /* codebook gain */
     211             : 
     212      378240 :         dist = g_pitch * g_pitch * coeff.y1y1 + g_pitch * coeff.xy1 + g_code * g_code * coeff.y2y2 + g_code * coeff.xy2 + g_pitch * g_code * coeff.y1y2;
     213             : 
     214      378240 :         if ( dist < dist_min )
     215             :         {
     216       61769 :             dist_min = dist;
     217       61769 :             index = i;
     218             :         }
     219             :     }
     220             : 
     221        3020 :     *gain_pit = (float) ( t_qua_gain[index * 2] ) / ( 1 << 14 );
     222        3020 :     *gain_code = (float) ( t_qua_gain[index * 2 + 1] ) / ( 1 << 11 ) * gcode0;
     223             : 
     224        3020 :     *past_gcode = *gain_code / *gain_inov;
     225             : 
     226        3020 :     return index;
     227             : }
     228             : 
     229             : /*---------------------------------------------------------------------*
     230             :  * procedure gain_enc_uv
     231             :  * Quantization of pitch and codebook gains.
     232             :  * - an initial predicted gain, gcode0, is first determined based on
     233             :  *   the predicted scaled innovation energy
     234             :  * - the correction  factor gamma = g_code / gcode0 is then vector quantized
     235             :  *   along with gain_pit
     236             :  * - the mean-squared weighted error criterion is used for the quantizer search
     237             :  *---------------------------------------------------------------------*/
     238             : 
     239           0 : static int16_t gain_enc_uv(
     240             :     const float *code,    /* i    : algebraic excitation                                            */
     241             :     const int16_t lcode,  /* i )  : Subframe size                                                   */
     242             :     float *gain_pit,      /* o    : quantized pitch gain                                            */
     243             :     float *gain_code,     /* o    : quantized codebook gain                                         */
     244             :     ACELP_CbkCorr *coeff, /* i/o  : correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> */
     245             :     float *past_gcode,    /* i/o  : past gain of code                                               */
     246             :     float *gain_inov      /* o    : unscaled innovation gain                                        */
     247             : )
     248             : {
     249             :     int16_t index;
     250             :     float g_code, g_code_corr;
     251             : 
     252             :     /*-----------------------------------------------------------------*
     253             :      * - calculate the unscaled innovation energy
     254             :      *-----------------------------------------------------------------*/
     255             : 
     256           0 :     *gain_inov = 1.0f / (float) sqrt( ( dotp( code, code, lcode ) + 0.01f ) / lcode );
     257             : 
     258           0 :     g_code_corr = coeff->xy2 / ( coeff->y2y2 * ( *gain_inov ) ); /*Correlation based*/
     259             : 
     260           0 :     g_code = g_code_corr;
     261             : 
     262             :     /*90dB max of gain for 2^15 amplitude code, */
     263           0 :     if ( g_code > 0.000001f )
     264             :     {
     265           0 :         index = (int16_t) ( ( ( 20.f * log10( g_code ) + 30.f ) / 1.9f ) + 0.5f );
     266             : 
     267           0 :         if ( index > 63 )
     268             :         {
     269           0 :             index = 63;
     270             :         }
     271           0 :         else if ( index < 0 )
     272             :         {
     273           0 :             index = 0;
     274             :         }
     275             :     }
     276             :     else
     277             :     {
     278           0 :         index = 0;
     279             :     }
     280             : 
     281           0 :     *gain_code = (float) pow( 10.f, ( ( ( index * 1.9f ) - 30.f ) / 20.f ) );
     282           0 :     *past_gcode = *gain_code; /*unscaled gain*/
     283           0 :     *gain_code *= *gain_inov; /*scaled gain*/
     284           0 :     *gain_pit = 0.f;
     285             : 
     286           0 :     return index;
     287             : }
     288             : 
     289             : /*---------------------------------------------------------------------*
     290             :  * procedure gain_enc_gacelp_uv
     291             :  * Quantization of pitch and codebook gains.
     292             :  * - an initial predicted gain, gcode0, is first determined based on
     293             :  *   the predicted scaled innovation energy
     294             :  * - the correction  factor gamma = g_code / gcode0 is then vector quantized
     295             :  *   along with gain_pit
     296             :  * - the mean-squared weighted error criterion is used for the quantizer search
     297             :  *---------------------------------------------------------------------*/
     298             : 
     299        8148 : int16_t gain_enc_gacelp_uv(
     300             :     const float *code,              /* i  : algebraic excitation                                            */
     301             :     const float *code2,             /* i  : gaussian excitation                                             */
     302             :     const int16_t lcode,            /* i  : Subframe size                                                   */
     303             :     const float mean_ener,          /* i  : quantized mean energy of the frame                              */
     304             :     float *gain_pit,                /* o  : quantized pitch gain                                            */
     305             :     float *gain_code,               /* o  : quantized codebook gain                                         */
     306             :     float *gain_code2,              /* o  : quantized codebook gain                                         */
     307             :     ACELP_CbkCorr *coeff,           /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> */
     308             :     float *past_gcode,              /* i/o: past gain of code                                               */
     309             :     float *gain_inov,               /* o  : unscaled innovation gain                                        */
     310             :     const int16_t noisy_speech_flag /* i  : noisy speech flag                                               */
     311             : )
     312             : {
     313             :     int16_t index;
     314             :     float gcode, gcode2, pred_nrg_frame;
     315             :     float norm_code2;
     316             :     int16_t i;
     317             :     float c, c_index2, c_first;
     318             :     int16_t index2;
     319             : 
     320             :     /*-----------------------------------------------------------------*
     321             :      * - calculate the unscaled innovation energy
     322             :      *-----------------------------------------------------------------*/
     323             : 
     324        8148 :     *gain_inov = 1.0f / (float) sqrt( ( dotp( code, code, lcode ) + 0.01f ) / lcode );
     325        8148 :     pred_nrg_frame = (float) pow( 10.0, mean_ener / 20.0 );
     326        8148 :     gcode = pred_nrg_frame * ( *gain_inov );
     327        8148 :     norm_code2 = 1.0f / (float) sqrt( ( dotp( code2, code2, lcode ) + 0.01f ) / lcode );
     328        8148 :     gcode2 = pred_nrg_frame * ( norm_code2 );
     329             : 
     330             :     /*-----------------------------------------------------------------*
     331             :      * search for the best quantizer
     332             :      *-----------------------------------------------------------------*/
     333             : 
     334        8148 :     *gain_code = coeff->xy2 / ( coeff->y2y2 * gcode );
     335             : 
     336        8148 :     if ( *gain_code > 0.000001f )
     337             :     {
     338        8148 :         index = (int16_t) ( ( ( 20.f * log10( *gain_code ) + 20.f ) / 1.25f ) + 0.5f );
     339             : 
     340        8148 :         if ( index > 31 )
     341             :         {
     342           8 :             index = 31;
     343             :         }
     344        8140 :         else if ( index < 0 )
     345             :         {
     346           4 :             index = 0;
     347             :         }
     348             :     }
     349             :     else
     350             :     {
     351           0 :         index = 0;
     352             :     }
     353             : 
     354        8148 :     *gain_code = (float) pow( 10.f, ( ( ( index * 1.25f ) - 20.f ) / 20.f ) );
     355        8148 :     *gain_code *= gcode;
     356             : 
     357        8148 :     if ( noisy_speech_flag )
     358             :     {
     359         528 :         c_first = 0.8f * coeff->xx - ( *gain_code ) * ( *gain_code ) * coeff->y2y2;
     360             :     }
     361             :     else
     362             :     {
     363        7620 :         c_first = coeff->xx - ( *gain_code ) * ( *gain_code ) * coeff->y2y2;
     364             :     }
     365        8148 :     index2 = 0;
     366        8148 :     *gain_code2 = (float) ( index2 * 0.25f + 0.25f ) * ( *gain_code * ( gcode2 / gcode ) );
     367             : 
     368        8148 :     c_index2 = c_first - ( *gain_code2 ) * ( *gain_code2 ) * coeff->y1y1 - 2 * ( *gain_code ) * ( *gain_code2 ) * coeff->y1y2;
     369             : 
     370       32592 :     for ( i = 1; i < 4; i++ )
     371             :     {
     372       24444 :         *gain_code2 = (float) ( i * 0.25f + 0.25f ) * ( *gain_code * ( gcode2 / gcode ) );
     373             : 
     374       24444 :         c = c_first - ( *gain_code2 ) * ( *gain_code2 ) * coeff->y1y1 - 2 * ( *gain_code ) * ( *gain_code2 ) * coeff->y1y2;
     375             : 
     376       24444 :         if ( fabs( c ) < fabs( c_index2 ) )
     377             :         {
     378       16638 :             index2 = i;
     379       16638 :             c_index2 = c;
     380             :         }
     381             :     }
     382             : 
     383        8148 :     *gain_code2 = (float) ( index2 * 0.25f + 0.25f ) * ( *gain_code * ( gcode2 / gcode ) );
     384        8148 :     index += index2 * 32;
     385             : 
     386        8148 :     *gain_pit = 0.f;
     387        8148 :     *past_gcode = *gain_code / *gain_inov; /*unscaled gain*/
     388             : 
     389        8148 :     return index;
     390             : }

Generated by: LCOV version 1.14