LCOV - code coverage report
Current view: top level - lib_enc - enc_pit_exc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 8834b716eb6d7dfb881d5c69dd21cb18e1692722 Lines: 118 139 84.9 %
Date: 2025-07-09 08:36:12 Functions: 1 1 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 "cnst.h"
      43             : #include "rom_com.h"
      44             : #include "prot.h"
      45             : #include "wmc_auto.h"
      46             : 
      47             : /*-------------------------------------------------------------------*
      48             :  * enc_pit_exc()
      49             :  *
      50             :  * Encode pitch only contribution
      51             :  *-------------------------------------------------------------------*/
      52             : 
      53       15245 : void enc_pit_exc(
      54             :     Encoder_State *st,                  /* i/o: State structure                                  */
      55             :     const float *speech,                /* i  : Input speech                                     */
      56             :     const float Aw[],                   /* i  : weighted A(z) unquantized for subframes          */
      57             :     const float *Aq,                    /* i  : 12k8 Lp coefficient                              */
      58             :     const float Es_pred,                /* i  : predicted scaled innov. energy                   */
      59             :     const float *res,                   /* i  : residual signal                                  */
      60             :     float *synth,                       /* i/o: core synthesis                                   */
      61             :     float *exc,                         /* i/o: current non-enhanced excitation                  */
      62             :     int16_t *T0,                        /* i/o: close loop integer pitch                         */
      63             :     int16_t *T0_frac,                   /* i/o: close-loop pitch period - fractional part        */
      64             :     float *pitch_buf,                   /* i/o: Fractionnal per subframe pitch                   */
      65             :     const int16_t nb_subfr,             /* i  : Number of subframe considered                    */
      66             :     float *gpit,                        /* o  : pitch mean gpit                                  */
      67             :     const int16_t tdm_Pitch_reuse_flag, /* i  : primary channel pitch reuse flag                 */
      68             :     const float tdm_Pri_pitch_buf[]     /* i  : primary channel pitch buffer                     */
      69             : )
      70             : {
      71             :     float xn[PIT_EXC_L_SUBFR];             /* Target vector for pitch search    */
      72             :     float xn2[PIT_EXC_L_SUBFR];            /* Target vector for codebook search */
      73             :     float cn[PIT_EXC_L_SUBFR];             /* Target vector in residual domain  */
      74             :     float h1[PIT_EXC_L_SUBFR + ( M + 1 )]; /* Impulse response vector           */
      75             :     float y1[PIT_EXC_L_SUBFR];             /* Filtered adaptive excitation      */
      76             :     float code[2 * L_SUBFR];               /* Fixed codebook excitation         */
      77             :     float y2[2 * L_SUBFR];                 /* Filtered algebraic excitation     */
      78             :     float voice_fac;                       /* Voicing factor                    */
      79             :     float gain_code;                       /* Gain of code                      */
      80             :     float gain_inov;                       /* inovation gain                    */
      81             :     float gain_pit;                        /* Pitch gain                        */
      82             :     int16_t pit_idx, i_subfr;              /* tmp variables                     */
      83             :     int16_t T0_min, T0_max;                /* pitch variables                   */
      84             :     float g_corr[10];                      /* ACELP correlation values + gain pitch */
      85             :     int16_t clip_gain, i;                  /* LSF clip gain and LP flag         */
      86             :     const float *p_Aw, *p_Aq;              /* pointer to LP filter coefficient vector */
      87             :     float *pt_pitch;                       /* pointer to floating pitch         */
      88             :     int16_t L_subfr;
      89             :     float cum_gpit, gpit_tmp;
      90             :     int32_t Local_BR, Pitch_BR;
      91             :     int16_t Pitch_CT, unbits_PI;
      92             :     float norm_gain_code;
      93             :     int16_t pitch_limit_flag;
      94             :     int16_t lp_select, lp_flag;
      95       15245 :     BSTR_ENC_HANDLE hBstr = st->hBstr;
      96             :     int16_t use_fcb;
      97             :     float gains_mem[2 * ( NB_SUBFR - 1 )]; /* pitch gain and code gain from previous subframes */
      98             : 
      99       15245 :     LPD_state_HANDLE hLPDmem = st->hLPDmem;
     100             : 
     101             :     /*------------------------------------------------------------------*
     102             :      * Initialization
     103             :      *------------------------------------------------------------------*/
     104             : 
     105       15245 :     pitch_limit_flag = 1; /* always extended pitch Q range */
     106       15245 :     use_fcb = 0;
     107       15245 :     unbits_PI = 0;
     108             : 
     109       15245 :     if ( st->GSC_IVAS_mode > 0 && ( st->GSC_noisy_speech || st->core_brate > GSC_H_RATE_STG ) )
     110             :     {
     111         118 :         Local_BR = ACELP_8k00;
     112         118 :         Pitch_CT = GENERIC;
     113         118 :         Pitch_BR = ACELP_8k00;
     114         118 :         if ( st->L_frame == L_FRAME16k )
     115             :         {
     116           0 :             Local_BR = ACELP_14k80;
     117           0 :             if ( st->GSC_IVAS_mode > 0 )
     118             :             {
     119           0 :                 Local_BR = ACELP_9k60;
     120             :             }
     121           0 :             Pitch_BR = st->core_brate;
     122             :         }
     123             :     }
     124       15127 :     else if ( st->GSC_noisy_speech )
     125             :     {
     126         689 :         Local_BR = ACELP_7k20;
     127         689 :         Pitch_CT = GENERIC;
     128         689 :         Pitch_BR = ACELP_7k20;
     129         689 :         if ( st->L_frame == L_FRAME16k )
     130             :         {
     131           0 :             Pitch_BR = st->core_brate;
     132             :         }
     133             :     }
     134             :     else
     135             :     {
     136       14438 :         Local_BR = ACELP_7k20;
     137       14438 :         Pitch_CT = AUDIO;
     138       14438 :         Pitch_BR = st->core_brate;
     139             : 
     140       14438 :         if ( st->L_frame == L_FRAME16k )
     141             :         {
     142        2637 :             Local_BR = ACELP_13k20;
     143        2637 :             Pitch_CT = GENERIC;
     144             :         }
     145             :     }
     146             : 
     147       15245 :     gain_code = 0;
     148             : 
     149       15245 :     if ( st->L_frame == L_FRAME16k )
     150             :     {
     151        2637 :         T0_max = PIT16k_MAX;
     152        2637 :         T0_min = PIT16k_MIN;
     153             :     }
     154             :     else
     155             :     {
     156       12608 :         T0_max = PIT_MAX;
     157       12608 :         T0_min = PIT_MIN;
     158             :     }
     159             : 
     160       15245 :     cum_gpit = 0.0f;
     161             : 
     162       15245 :     L_subfr = st->L_frame / nb_subfr;
     163             : 
     164       15245 :     lp_flag = st->acelp_cfg.ltf_mode;
     165             : 
     166       15245 :     if ( ( ( st->core_brate >= MIN_RATE_FCB || ( st->GSC_noisy_speech == 1 && ( ( st->L_frame == L_FRAME && st->core_brate >= ACELP_13k20 ) || ( st->L_frame == L_FRAME16k && st->core_brate >= GSC_H_RATE_STG ) || st->GSC_IVAS_mode == 0 ) ) ) && L_subfr == L_SUBFR ) )
     167             :     {
     168         689 :         use_fcb = 1;
     169             :     }
     170       14556 :     else if ( st->GSC_IVAS_mode > 0 && L_subfr == 2 * L_SUBFR && st->GSC_IVAS_mode < 3 )
     171             :     {
     172        2043 :         use_fcb = 2;
     173        2043 :         st->acelp_cfg.fcb_mode = 1;
     174        2043 :         set_s( st->acelp_cfg.gains_mode, 6, NB_SUBFR );
     175        2043 :         set_s( st->acelp_cfg.pitch_bits, 9, NB_SUBFR );
     176        2043 :         set_s( st->acelp_cfg.fixed_cdk_index, 14, NB_SUBFR16k );
     177             :     }
     178             : 
     179             :     /*------------------------------------------------------------------*
     180             :      * ACELP subframe loop
     181             :      *------------------------------------------------------------------*/
     182             : 
     183       15245 :     p_Aw = Aw;
     184       15245 :     p_Aq = Aq;
     185       15245 :     pt_pitch = pitch_buf; /* pointer to the pitch buffer */
     186             : 
     187       44721 :     for ( i_subfr = 0; i_subfr < st->L_frame; i_subfr += L_subfr )
     188             :     {
     189             :         /*----------------------------------------------------------------*
     190             :          * Find the the excitation search target "xn" and innovation
     191             :          *   target in residual domain "cn"
     192             :          * Compute impulse response, h1[], of weighted synthesis filter
     193             :          *----------------------------------------------------------------*/
     194             : 
     195       29476 :         mvr2r( &res[i_subfr], &exc[i_subfr], L_subfr );
     196             : 
     197       29476 :         find_targets( speech, st->hGSCEnc->mem_syn_tmp, i_subfr, &st->hGSCEnc->mem_w0_tmp, p_Aq, res, L_subfr, p_Aw, st->preemph_fac, xn, cn, h1 );
     198             : 
     199             :         /*----------------------------------------------------------------*
     200             :          * Close-loop pitch search and quantization
     201             :          * Adaptive exc. construction
     202             :          *----------------------------------------------------------------*/
     203             : 
     204       29476 :         *pt_pitch = pit_encode( hBstr, st->acelp_cfg.pitch_bits, Pitch_BR, 0, st->L_frame, Pitch_CT, &pitch_limit_flag, i_subfr, exc, L_subfr, st->pitch, &T0_min, &T0_max, T0, T0_frac, h1, xn, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf );
     205             : 
     206             :         /*-----------------------------------------------------------------*
     207             :          * Find adaptive exitation
     208             :          *-----------------------------------------------------------------*/
     209             : 
     210       29476 :         pred_lt4( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_subfr + 1, inter4_2, L_INTERPOL2, PIT_UP_SAMP );
     211             : 
     212             :         /*-----------------------------------------------------------------*
     213             :          * Gain clipping test to avoid unstable synthesis on frame erasure
     214             :          * or in case of floating point encoder & fixed p. decoder
     215             :          *-----------------------------------------------------------------*/
     216             : 
     217       29476 :         clip_gain = gp_clip( st->element_mode, st->core_brate, st->voicing, i_subfr, AUDIO, xn, st->clip_var );
     218             : 
     219             :         /*-----------------------------------------------------------------*
     220             :          * Codebook target computation
     221             :          * (No LP filtering of the adaptive excitation)
     222             :          *-----------------------------------------------------------------*/
     223             : 
     224       29476 :         lp_select = lp_filt_exc_enc( MODE1, AUDIO, i_subfr, exc, h1, xn, y1, xn2, L_subfr, st->L_frame, g_corr, clip_gain, &gain_pit, &lp_flag );
     225             : 
     226       29476 :         if ( lp_flag == NORMAL_OPERATION )
     227             :         {
     228           0 :             push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 );
     229             :         }
     230             : 
     231             :         /* update long-term pitc hgain for speech/music classifier */
     232       29476 :         st->hSpMusClas->lowrate_pitchGain = 0.9f * st->hSpMusClas->lowrate_pitchGain + 0.1f * gain_pit;
     233             : 
     234       29476 :         gpit_tmp = gain_pit;
     235             : 
     236       29476 :         if ( use_fcb == 0 )
     237             :         {
     238       22634 :             if ( st->core_brate >= MIN_RATE_FCB )
     239             :             {
     240         868 :                 pit_idx = (int16_t) vquant( &gain_pit, mean_gp, &gain_pit, dic_gp, 1, 32 );
     241         868 :                 push_indice( hBstr, IND_PIT_IDX, pit_idx, 5 );
     242             :             }
     243             :             else
     244             :             {
     245       21766 :                 pit_idx = (int16_t) vquant( &gain_pit, mean_gp, &gain_pit, dic_gp, 1, 16 );
     246       21766 :                 push_indice( hBstr, IND_PIT_IDX, pit_idx, 4 );
     247             :             }
     248             :         }
     249        6842 :         else if ( use_fcb == 2 )
     250             :         {
     251             :             /*-----------------------------------------------------------------*
     252             :              * Innovation encoding
     253             :              *-----------------------------------------------------------------*/
     254             : 
     255        4086 :             inov_encode( st, st->core_brate, 0, st->L_frame, st->last_L_frame, GENERIC, st->bwidth, 0, i_subfr, -1, p_Aq, gain_pit, cn, exc, h1, hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &i, 2 * L_SUBFR );
     256             : 
     257             :             /*-----------------------------------------------------------------*
     258             :              * Gain encoding
     259             :              *-----------------------------------------------------------------*/
     260             : 
     261        4086 :             gain_enc_lbr( st->hBstr, st->acelp_cfg.gains_mode, GENERIC, i_subfr, xn, y1, y2, code, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, gains_mem, clip_gain, 2 * L_SUBFR );
     262             :         }
     263             :         else
     264             :         {
     265             :             /*-----------------------------------------------------------------*
     266             :              * Innovation & gain encoding
     267             :              *-----------------------------------------------------------------*/
     268             : 
     269        2756 :             inov_encode( st, Local_BR, 0, st->L_frame, st->last_L_frame, LOCAL_CT, WB, 1, i_subfr, -1, p_Aq, gain_pit, cn, exc, h1, hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &unbits_PI, L_SUBFR );
     270             : 
     271        2756 :             gain_enc_mless( hBstr, st->acelp_cfg.gains_mode, st->element_mode, st->L_frame, i_subfr, -1, xn, y1, y2, code, Es_pred, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, clip_gain );
     272             :         }
     273             : 
     274       29476 :         gp_clip_test_gain_pit( st->element_mode, st->core_brate, gain_pit, st->clip_var );
     275             : 
     276       29476 :         if ( use_fcb != 0 )
     277             :         {
     278        6842 :             hLPDmem->tilt_code = est_tilt( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, L_subfr, 0 );
     279             :         }
     280             :         else
     281             :         {
     282       22634 :             hLPDmem->tilt_code = 0.0f;
     283             :         }
     284             : 
     285             :         /*-----------------------------------------------------------------*
     286             :          * Update memory of the weighting filter
     287             :          *-----------------------------------------------------------------*/
     288             : 
     289       29476 :         if ( use_fcb != 0 )
     290             :         {
     291        6842 :             st->hGSCEnc->mem_w0_tmp = xn[L_subfr - 1] - ( gain_pit * y1[L_subfr - 1] ) - ( gain_code * y2[L_subfr - 1] );
     292             :         }
     293             :         else
     294             :         {
     295       22634 :             st->hGSCEnc->mem_w0_tmp = xn[L_subfr - 1] - ( gain_pit * y1[L_subfr - 1] );
     296             :         }
     297             : 
     298             :         /*-----------------------------------------------------------------*
     299             :          * Construct adaptive part of the excitation
     300             :          * Save the non-enhanced excitation for FEC_exc
     301             :          *-----------------------------------------------------------------*/
     302             : 
     303       29476 :         if ( use_fcb != 0 )
     304             :         {
     305      706234 :             for ( i = 0; i < L_subfr; i++ )
     306             :             {
     307      699392 :                 exc[i + i_subfr] = gain_pit * exc[i + i_subfr] + gain_code * code[i];
     308             :             }
     309             :         }
     310             :         else
     311             :         {
     312     3394730 :             for ( i = 0; i < L_subfr; i++ )
     313             :             {
     314     3372096 :                 exc[i + i_subfr] = gain_pit * exc[i + i_subfr];
     315             :             }
     316             :         }
     317             : 
     318             :         /*-----------------------------------------------------------------*
     319             :          * Synthesize speech to update mem_syn[].
     320             :          * Update A(z) filters
     321             :          *-----------------------------------------------------------------*/
     322             : 
     323       29476 :         syn_filt( p_Aq, M, &exc[i_subfr], &synth[i_subfr], L_subfr, st->hGSCEnc->mem_syn_tmp, 1 );
     324             : 
     325       29476 :         if ( L_subfr == 5 * L_SUBFR )
     326             :         {
     327        2637 :             cum_gpit = gpit_tmp;
     328             : 
     329        2637 :             pt_pitch++;
     330        2637 :             *pt_pitch = *( pt_pitch - 1 );
     331        2637 :             pt_pitch++;
     332        2637 :             *pt_pitch = *( pt_pitch - 1 );
     333        2637 :             pt_pitch++;
     334        2637 :             *pt_pitch = *( pt_pitch - 1 );
     335        2637 :             pt_pitch++;
     336        2637 :             *pt_pitch = *( pt_pitch - 1 );
     337        2637 :             pt_pitch++;
     338             : 
     339        2637 :             p_Aw += 5 * ( M + 1 );
     340        2637 :             p_Aq += 5 * ( M + 1 );
     341             :         }
     342       26839 :         else if ( L_subfr == 5 * L_SUBFR / 2 )
     343             :         {
     344           0 :             if ( i_subfr == 0 )
     345             :             {
     346           0 :                 cum_gpit = gpit_tmp * .4f;
     347           0 :                 pt_pitch++;
     348           0 :                 *pt_pitch = *( pt_pitch - 1 );
     349           0 :                 pt_pitch++;
     350           0 :                 p_Aw += 2 * ( M + 1 );
     351           0 :                 p_Aq += 2 * ( M + 1 );
     352             :             }
     353             :             else
     354             :             {
     355           0 :                 cum_gpit += gpit_tmp * .6f;
     356           0 :                 pt_pitch++;
     357           0 :                 *pt_pitch = *( pt_pitch - 1 );
     358           0 :                 pt_pitch++;
     359           0 :                 *pt_pitch = *( pt_pitch - 1 );
     360           0 :                 pt_pitch++;
     361           0 :                 p_Aw += 3 * ( M + 1 );
     362           0 :                 p_Aq += 3 * ( M + 1 );
     363             :             }
     364             :         }
     365       26839 :         else if ( L_subfr == 2 * L_SUBFR )
     366             :         {
     367        6682 :             if ( i_subfr == 0 )
     368             :             {
     369        3341 :                 cum_gpit = gpit_tmp * .5f;
     370             :             }
     371             :             else
     372             :             {
     373        3341 :                 cum_gpit += gpit_tmp * .5f;
     374             :             }
     375             : 
     376        6682 :             p_Aw += 2 * ( M + 1 );
     377        6682 :             p_Aq += 2 * ( M + 1 );
     378        6682 :             pt_pitch++;
     379        6682 :             *pt_pitch = *( pt_pitch - 1 );
     380        6682 :             pt_pitch++;
     381             :         }
     382       20157 :         else if ( L_subfr == 4 * L_SUBFR )
     383             :         {
     384        5637 :             cum_gpit = gpit_tmp;
     385             : 
     386        5637 :             pt_pitch++;
     387        5637 :             *pt_pitch = *( pt_pitch - 1 );
     388        5637 :             pt_pitch++;
     389        5637 :             *pt_pitch = *( pt_pitch - 1 );
     390        5637 :             pt_pitch++;
     391        5637 :             *pt_pitch = *( pt_pitch - 1 );
     392        5637 :             pt_pitch++;
     393             : 
     394        5637 :             p_Aw += 4 * ( M + 1 );
     395        5637 :             p_Aq += 4 * ( M + 1 );
     396             :         }
     397             :         else
     398             :         {
     399       14520 :             if ( i_subfr == 0 )
     400             :             {
     401        3630 :                 cum_gpit = gpit_tmp * .25f;
     402             :             }
     403             :             else
     404             :             {
     405       10890 :                 cum_gpit += gpit_tmp * .25f;
     406             :             }
     407             : 
     408       14520 :             pt_pitch++;
     409       14520 :             p_Aw += ( M + 1 );
     410       14520 :             p_Aq += ( M + 1 );
     411             :         }
     412             :     }
     413             : 
     414       15245 :     *gpit = 0.1f * *gpit + 0.9f * cum_gpit;
     415             : 
     416       15245 :     return;
     417             : }

Generated by: LCOV version 1.14