LCOV - code coverage report
Current view: top level - lib_enc - hf_cod_amrwb.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 7 90 7.8 %
Date: 2025-05-23 08:37:30 Functions: 1 4 25.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 hp400_12k8( float signal[], const int16_t lg, float mem[] );
      53             : static void filt_6k_8k( float signal[], const int16_t lg, float mem[] );
      54             : 
      55             : 
      56             : /*---------------------------------------------------------------------*
      57             :  * hf_cod_init()
      58             :  *
      59             :  *
      60             :  *---------------------------------------------------------------------*/
      61             : 
      62           3 : void hf_cod_init(
      63             :     float *mem_hp400_enc,  /* o  : memory of hp 400 Hz filter   */
      64             :     float *mem_hf1_enc,    /* o  : HF band-pass filter memory   */
      65             :     float *mem_syn_hf_enc, /* o  : HF synthesis memory          */
      66             :     float *mem_hf2_enc,    /* o  : HF band-pass filter memory   */
      67             :     float *gain_alpha      /* o  : smoothing gain for transitions between active and inactive frames */
      68             : )
      69             : {
      70           3 :     set_f( mem_hp400_enc, 0, 4 );
      71           3 :     set_f( mem_hf1_enc, 0, L_FIR - 1 );
      72           3 :     set_f( mem_syn_hf_enc, 0, M );
      73           3 :     set_f( mem_hf2_enc, 0, L_FIR - 1 );
      74           3 :     *gain_alpha = 1.0;
      75             : 
      76           3 :     return;
      77             : }
      78             : 
      79             : 
      80             : /*---------------------------------------------------------------------*
      81             :  * hf_cod()
      82             :  *
      83             :  *
      84             :  *---------------------------------------------------------------------*/
      85             : 
      86           0 : void hf_cod(
      87             :     const int32_t core_brate, /* i  : core bitrate                 */
      88             :     const float *speech16k,   /* i  : original speech at 16 kHz    */
      89             :     const float Aq[],         /* i  : quantized Aq                 */
      90             :     const float exc[],        /* i  : excitation at 12.8 kHz       */
      91             :     float synth[],            /* i  : 12.8kHz synthesis signal     */
      92             :     int16_t *seed2_enc,       /* i/o: random seed for HF noise gen */
      93             :     float *mem_hp400_enc,     /* i/o: memory of hp 400 Hz filter   */
      94             :     float *mem_syn_hf_enc,    /* i/o: HF synthesis memory          */
      95             :     float *mem_hf1_enc,       /* i/o: HF band-pass filter memory   */
      96             :     float *mem_hf2_enc,       /* i/o: HF band-pass filter memory   */
      97             :     const int16_t *dtxHangoverCount,
      98             :     float *gain_alpha, /* i/o: smoothing gain for transitions between active and inactive frames */
      99             :     int16_t *hf_gain   /* o  :  HF gain to be transmitted to decoder */
     100             : )
     101             : {
     102             :     int16_t i;
     103             :     float ener_hf, ener_exc, ener_input, fac, HF_syn[L_SUBFR16k], tmp, ener, scale;
     104             :     float Ap[M16k + 1];
     105             :     float HF_SP[L_SUBFR16k];
     106             :     float HF_est_gain;
     107             :     float HF_calc_gain;
     108             :     float HF_corr_gain;
     109             :     int16_t HF_gain_ind;
     110             :     float dist_min, dist;
     111             :     float HF[L_SUBFR16k]; /* HF excitation               */
     112             : 
     113             :     /* Original speech signal as reference for high band gain quantisation */
     114           0 :     for ( i = 0; i < L_SUBFR16k; i++ )
     115             :     {
     116           0 :         HF_SP[i] = speech16k[i];
     117             :     }
     118             : 
     119             :     /*-----------------------------------------------------------------*
     120             :      * generate white noise vector
     121             :      *-----------------------------------------------------------------*/
     122             : 
     123           0 :     for ( i = 0; i < L_SUBFR16k; i++ )
     124             :     {
     125           0 :         HF[i] = (float) own_random( seed2_enc );
     126             :     }
     127             : 
     128             :     /*-----------------------------------------------------------------*
     129             :      * calculate energy scaling factor so that white noise would have the
     130             :      * same energy as exc12k8
     131             :      *-----------------------------------------------------------------*/
     132             : 
     133           0 :     ener_exc = 0.01f;
     134           0 :     for ( i = 0; i < L_SUBFR; i++ )
     135             :     {
     136           0 :         ener_exc += exc[i] * exc[i];
     137             :     }
     138             : 
     139           0 :     ener_hf = 0.01f;
     140           0 :     for ( i = 0; i < L_SUBFR16k; i++ )
     141             :     {
     142           0 :         ener_hf += HF[i] * HF[i];
     143             :     }
     144             : 
     145           0 :     scale = (float) ( sqrt( ener_exc / ener_hf ) );
     146             : 
     147           0 :     for ( i = 0; i < L_SUBFR16k; i++ )
     148             :     {
     149           0 :         HF[i] *= scale;
     150             :     }
     151             : 
     152             :     /*-----------------------------------------------------------------*
     153             :      * calculate energy scaling factor to respect tilt of synth12k8
     154             :      * (tilt: 1=voiced, -1=unvoiced)
     155             :      *-----------------------------------------------------------------*/
     156             : 
     157           0 :     hp400_12k8( synth, L_SUBFR, mem_hp400_enc );
     158             : 
     159           0 :     ener = 0.001f;
     160           0 :     tmp = 0.001f;
     161           0 :     for ( i = 1; i < L_SUBFR; i++ )
     162             :     {
     163           0 :         ener += synth[i] * synth[i];    /* ener = r[0] */
     164           0 :         tmp += synth[i] * synth[i - 1]; /* tmp  = r[1] */
     165             :     }
     166           0 :     fac = tmp / ener;
     167             : 
     168           0 :     HF_est_gain = (float) ( 1.0f - fac );
     169           0 :     if ( core_brate == SID_1k75 || core_brate == FRAME_NO_DATA )
     170             :     {
     171             :         /* emphasize HF noise in CNG */
     172           0 :         HF_est_gain *= 1.25f; /* full alignment with G.722 and AMR-WB */
     173             :     }
     174             : 
     175           0 :     if ( HF_est_gain < 0.1f )
     176             :     {
     177           0 :         HF_est_gain = 0.1f;
     178             :     }
     179             : 
     180           0 :     if ( HF_est_gain > 1.0f ) /* this condition is not in G.722.2, but in AMR-WB!*/
     181             :     {
     182           0 :         HF_est_gain = 1.0f;
     183             :     }
     184             : 
     185             :     /*-----------------------------------------------------------------*
     186             :      * synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz
     187             :      *-----------------------------------------------------------------*/
     188             : 
     189           0 :     weight_a( Aq, Ap, 0.6f, M );
     190           0 :     syn_filt( Ap, M, HF, HF_syn, L_SUBFR16k, mem_syn_hf_enc, 1 );
     191             : 
     192             :     /*-----------------------------------------------------------------*
     193             :      * high pass filtering (0.9375ms of delay = 15 samples@16k)
     194             :      *-----------------------------------------------------------------*/
     195             : 
     196           0 :     filt_6k_8k( HF_syn, L_SUBFR16k, mem_hf1_enc );
     197             : 
     198             :     /* filtering of the original signal */
     199           0 :     filt_6k_8k( HF_SP, L_SUBFR16k, mem_hf2_enc );
     200             : 
     201             :     /* check the gain difference */
     202           0 :     ener_input = 0.01f;
     203           0 :     ener_hf = 0.01f;
     204           0 :     for ( i = 0; i < L_SUBFR16k; i++ )
     205             :     {
     206           0 :         ener_input += HF_SP[i] * HF_SP[i];
     207           0 :         ener_hf += HF_syn[i] * HF_syn[i];
     208             :     }
     209             : 
     210           0 :     HF_calc_gain = (float) sqrt( ener_input / ener_hf );
     211             : 
     212             :     /* set energy of HF synthesis to energy of original HF:
     213             :        cross-fade between HF levels in active and inactive frame in hangover period */
     214             : 
     215           0 :     *gain_alpha *= (float) ( 10 - ( *dtxHangoverCount ) ) / 7.0f;
     216           0 :     if ( ( 10 - ( *dtxHangoverCount ) ) > 6 )
     217             :     {
     218           0 :         *gain_alpha = 1.0f;
     219             :     }
     220             : 
     221           0 :     HF_corr_gain = ( *gain_alpha ) * HF_calc_gain + ( 1.0f - ( *gain_alpha ) ) * HF_est_gain;
     222           0 :     HF_corr_gain /= 2.0f; /* to stay in aligned with AMR-WB legacy decoder where decoded gain is multiplied by 2 */
     223             : 
     224             :     /* Quantize the correction gain */
     225           0 :     dist_min = 100000.0f;
     226           0 :     HF_gain_ind = 0;
     227           0 :     for ( i = 0; i < 16; i++ )
     228             :     {
     229           0 :         dist = ( HF_corr_gain - HP_gain[i] ) * ( HF_corr_gain - HP_gain[i] );
     230           0 :         if ( dist_min > dist )
     231             :         {
     232           0 :             dist_min = dist;
     233           0 :             HF_gain_ind = i;
     234             :         }
     235             :     }
     236             : 
     237           0 :     *hf_gain = HF_gain_ind;
     238             : 
     239           0 :     return;
     240             : }
     241             : 
     242             : /*-----------------------------------------------------------------------*
     243             :  * Function hp400_12k8()                                                 *
     244             :  *                                                                       *
     245             :  * 2nd order Cheb2 high pass filter with cut off frequency at 400 Hz.    *
     246             :  * Optimized for fixed-point to get the following frequency response  :  *
     247             :  *                                                                       *
     248             :  *  frequency  :   0Hz   100Hz  200Hz  300Hz  400Hz  630Hz  1.5kHz  3kHz *
     249             :  *  dB loss  :   -infdB  -30dB  -20dB  -10dB  -3dB   +6dB    +1dB    0dB *
     250             :  *                                                                       *
     251             :  * Algorithm  :                                                          *
     252             :  *                                                                       *
     253             :  *  y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2]                         *
     254             :  *                   + a[1]*y[i-1] + a[2]*y[i-2];                        *
     255             :  *                                                                       *
     256             :  *  short b[3] = {3660, -7320,  3660};       in Q12                      *
     257             :  *  short a[3] = {4096,  7320, -3540};       in Q12                      *
     258             :  *                                                                       *
     259             :  *  float -->   b[3] = {0.893554687, -1.787109375,  0.893554687};        *
     260             :  *              a[3] = {1.000000000,  1.787109375, -0.864257812};        *
     261             :  *-----------------------------------------------------------------------*/
     262             : 
     263           0 : static void hp400_12k8(
     264             :     float signal[],   /* i/o: signal            */
     265             :     const int16_t lg, /* i  : length of signal  */
     266             :     float mem[]       /* i/o: filter memory [4] */
     267             : )
     268             : {
     269             :     int16_t i;
     270             :     float x0, x1, x2;
     271             :     float yy0, yy1, y2;
     272             : 
     273           0 :     yy1 = mem[0];
     274           0 :     y2 = mem[1];
     275           0 :     x0 = mem[2];
     276           0 :     x1 = mem[3];
     277           0 :     for ( i = 0; i < lg; i++ )
     278             :     {
     279           0 :         x2 = x1;
     280           0 :         x1 = x0;
     281           0 :         x0 = signal[i];
     282           0 :         yy0 = yy1 * a_hp400[1] + y2 * a_hp400[2] + x0 * b_hp400[0] + x1 * b_hp400[1] + x2 * b_hp400[2];
     283             : 
     284           0 :         signal[i] = yy0;
     285           0 :         y2 = yy1;
     286           0 :         yy1 = yy0;
     287             :     }
     288             : 
     289           0 :     mem[0] = yy1;
     290           0 :     mem[1] = y2;
     291           0 :     mem[2] = x0;
     292           0 :     mem[3] = x1;
     293             : 
     294           0 :     return;
     295             : }
     296             : 
     297             : /*-------------------------------------------------------------------*
     298             :  * filt_6k_7k:
     299             :  *
     300             :  * 15th order band pass 6kHz to 7kHz FIR filter.
     301             :  *
     302             :  * frequency  :4kHz   5kHz  5.5kHz  6kHz  6.5kHz 7kHz  7.5kHz  8kHz
     303             :  * dB loss  : -60dB  -45dB  -13dB   -3dB   0dB   -3dB  -13dB  -45dB
     304             :  * (gain=4.0)
     305             :  *-------------------------------------------------------------------*/
     306             : 
     307           0 : static void filt_6k_8k(
     308             :     float signal[],   /* i/o: signal        */
     309             :     const int16_t lg, /* i  : signal length */
     310             :     float mem[]       /* i/o: filter memory */
     311             : )
     312             : {
     313             :     int16_t i, j;
     314             :     float s, x[L_FRAME48k / NB_SUBFR + ( L_FIR - 1 )];
     315             : 
     316           0 :     for ( i = 0; i < ( L_FIR - 1 ); i++ )
     317             :     {
     318           0 :         x[i] = mem[i];
     319             :     }
     320             : 
     321           0 :     for ( i = 0; i < lg; i++ )
     322             :     {
     323           0 :         x[i + ( L_FIR - 1 )] = signal[i];
     324             :     }
     325             : 
     326           0 :     for ( i = 0; i < lg; i++ )
     327             :     {
     328           0 :         s = 0.0;
     329           0 :         for ( j = 0; j < L_FIR; j++ )
     330             :         {
     331           0 :             s += x[i + j] * fir_6k_8k[j];
     332             :         }
     333             : 
     334           0 :         signal[i] = (float) ( s * 1.0f );
     335             :     }
     336             : 
     337           0 :     for ( i = 0; i < ( L_FIR - 1 ); i++ )
     338             :     {
     339           0 :         mem[i] = x[i + lg];
     340             :     }
     341             : 
     342           0 :     return;
     343             : }

Generated by: LCOV version 1.14