LCOV - code coverage report
Current view: top level - lib_enc - guided_plc_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 101 104 97.1 %
Date: 2025-05-23 08:37:30 Functions: 7 7 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             : #include <math.h>
      40             : #include "prot.h"
      41             : #include "stat_enc.h"
      42             : #include "wmc_auto.h"
      43             : 
      44             : /*-------------------------------------------------------------------*
      45             :  * coderLookAheadInnovation()
      46             :  *
      47             :  *
      48             :  *-------------------------------------------------------------------*/
      49             : 
      50         315 : static void coderLookAheadInnovation(
      51             :     const float A[],       /* i  : coefficients NxAz[M+1]   */
      52             :     int16_t *pT,           /* o  : pitch                    */
      53             :     PLC_ENC_EVS_HANDLE st, /* i/o: coder memory state       */
      54             :     float *speechLookAhead,
      55             :     float *old_exc,
      56             :     const int16_t L_subfr,
      57             :     const int16_t L_frame )
      58             : {
      59             :     int16_t i;
      60             :     float *exc, exc_buf[L_EXC_MEM + 2 * L_SUBFR + 8];
      61         315 :     int16_t T0 = 0;
      62             :     int16_t prev_pitch;
      63             :     float ps, alp, max_ps;
      64             :     int16_t subfr_len;
      65             :     int16_t search_range;
      66             : 
      67         315 :     search_range = 9;
      68             : 
      69         315 :     set_f( exc_buf, 0.0f, L_EXC_MEM + 2 * L_SUBFR + 8 );
      70             : 
      71             :     /* Framing parameters */
      72         315 :     if ( L_frame < L_FRAME16k )
      73             :     {
      74           0 :         subfr_len = (int16_t) ( 1.75 * L_subfr );
      75             :     }
      76             :     else
      77             :     {
      78         315 :         subfr_len = (int16_t) ( 2 * L_subfr );
      79             :     }
      80             : 
      81             :     /*------------------------------------------------------------------------*
      82             :      * Initialize buffers                                                     *
      83             :      *------------------------------------------------------------------------*/
      84             : 
      85             :     /* set excitation memory */
      86         315 :     exc = exc_buf + L_EXC_MEM + 8;
      87         315 :     mvr2r( old_exc, exc_buf, L_EXC_MEM + 8 );
      88             : 
      89             :     /*------------------------------------------------------------------------*
      90             :      * - Get residual signal and target at lookahead part.                    *
      91             :      *------------------------------------------------------------------------*/
      92             : 
      93             :     /* find LP residual signal for look-ahead part */
      94         315 :     getLookAheadResSig( speechLookAhead, A, exc, L_frame, L_subfr, M, 2 );
      95             : 
      96             :     /* Initialize excitation buffer */
      97         315 :     prev_pitch = st->T0_4th;
      98             :     /* find target signals */
      99             :     /* find best candidate of pitch lag */
     100             :     {
     101         315 :         max_ps = -1.0e10;
     102         315 :         T0 = st->T0_4th;
     103        5985 :         for ( i = -search_range; i < search_range; i++ )
     104             :         {
     105        5670 :             if ( prev_pitch + i > st->pit_max || prev_pitch + i < st->pit_min )
     106             :             {
     107          35 :                 continue;
     108             :             }
     109        5635 :             ps = dotp( exc, &exc[-( prev_pitch + i )], subfr_len );
     110        5635 :             alp = dotp( &exc[-( prev_pitch + i )], &exc[-( prev_pitch + i )], subfr_len );
     111        5635 :             ps /= (float) sqrt( alp + 1.0e-10 );
     112        5635 :             if ( max_ps < ps )
     113             :             {
     114        1382 :                 max_ps = ps;
     115        1382 :                 T0 = prev_pitch + i;
     116             :             }
     117             :         }
     118         315 :         if ( max_ps < 0.0 )
     119             :         {
     120           0 :             T0 = st->T0_4th;
     121             :         }
     122             :     }
     123             : 
     124         315 :     pT[0] = T0;
     125             : 
     126         315 :     return;
     127             : }
     128             : 
     129             : 
     130             : /*-------------------------------------------------------------------*
     131             :  * getConcealedlsf()
     132             :  *
     133             :  *
     134             :  *-------------------------------------------------------------------*/
     135             : 
     136         935 : static void getConcealedlsf(
     137             :     PLC_ENC_EVS_HANDLE memDecState,
     138             :     const float lsfBase[],
     139             :     const int16_t L_frame,
     140             :     const int16_t last_good )
     141             : {
     142         935 :     float *lsf = memDecState->lsf_con;
     143             : 
     144         935 :     dlpc_bfi( L_frame, &lsf[0], memDecState->lsfold, last_good, 1 /*assumes packet loss */, memDecState->mem_MA, memDecState->mem_AR, &( memDecState->stab_fac ), memDecState->lsf_adaptive_mean, 1, NULL, 0, NULL, NULL, lsfBase );
     145             : 
     146         935 :     return;
     147             : }
     148             : 
     149             : 
     150             : /*-------------------------------------------------------------------*
     151             :  * enc_prm_side_Info()
     152             :  *
     153             :  *
     154             :  *-------------------------------------------------------------------*/
     155             : 
     156         975 : void enc_prm_side_Info(
     157             :     PLC_ENC_EVS_HANDLE hPlc_Ext,
     158             :     Encoder_State *st )
     159             : {
     160             :     int16_t diff_pitch;
     161             :     int16_t bits_per_subfr, search_range;
     162         975 :     BSTR_ENC_HANDLE hBstr = st->hBstr;
     163             : 
     164         975 :     bits_per_subfr = 4;
     165         975 :     search_range = 8;
     166             : 
     167         975 :     if ( hPlc_Ext->nBits > 1 )
     168             :     {
     169         431 :         push_next_indice( hBstr, 1, 1 );
     170             : 
     171         431 :         diff_pitch = hPlc_Ext->T0 - hPlc_Ext->T0_4th;
     172             : 
     173         431 :         if ( ( diff_pitch > search_range - 1 ) || ( diff_pitch < -search_range + 1 ) )
     174             :         {
     175          10 :             diff_pitch = -8;
     176             :         }
     177             : 
     178         431 :         push_next_indice( hBstr, ( diff_pitch + search_range ), bits_per_subfr );
     179             :     }
     180             :     else
     181             :     {
     182         544 :         push_next_indice( hBstr, 0, 1 );
     183             :     }
     184             : 
     185         975 :     return;
     186             : }
     187             : 
     188             : /*-------------------------------------------------------------------*
     189             :  * encoderSideLossSimulation()
     190             :  *
     191             :  * Encoder side loss simulation
     192             :  *-------------------------------------------------------------------*/
     193             : 
     194        1250 : void encoderSideLossSimulation(
     195             :     Encoder_State *st,
     196             :     PLC_ENC_EVS_HANDLE hPlc_Ext,
     197             :     float *lsf_q,
     198             :     const float stab_fac,
     199             :     const int16_t calcOnlylsf,
     200             :     const int16_t L_frame )
     201             : {
     202             :     float lspLocal[M];
     203             :     const float *lsfBase; /* base for differential lsf coding */
     204             : 
     205             :     /* Decoder State Update */
     206        1250 :     lsf2lsp( lsf_q, lspLocal, M, st->sr_core );
     207             : 
     208        1250 :     lsfBase = PlcGetlsfBase( st->lpcQuantization, st->narrowBand, st->sr_core );
     209             : 
     210        1250 :     mvr2r( st->mem_MA, hPlc_Ext->mem_MA, M );
     211             : 
     212             :     /* lsf parameter processing for concealment */
     213        1250 :     updatelsfForConcealment( hPlc_Ext, lsf_q );
     214        1250 :     hPlc_Ext->stab_fac = stab_fac;
     215             : 
     216             :     /* Update Decoder State for the loss simulation at the next frame */
     217        1250 :     mvr2r( lsf_q, hPlc_Ext->lsfold, M );
     218        1250 :     mvr2r( lspLocal, hPlc_Ext->lspold, M );
     219             : 
     220        1250 :     if ( calcOnlylsf )
     221             :     {
     222             :         /* lsf concealment simulation */
     223         935 :         getConcealedlsf( hPlc_Ext, lsfBase, L_frame, st->clas );
     224         935 :         hPlc_Ext->T0 = hPlc_Ext->T0_4th;
     225             :     }
     226             :     else
     227             :     {
     228             :         float AqCon[( NB_SUBFR16k + 1 ) * ( M + 1 )];
     229             :         float *speechLookAhead;
     230             :         float old_exc[L_EXC_MEM + 8];
     231             : 
     232             :         /*                 Initialize pointers here                  */
     233         315 :         mvr2r( hPlc_Ext->old_exc, old_exc, 8 );
     234         315 :         mvr2r( hPlc_Ext->LPDmem->old_exc, &old_exc[8], L_EXC_MEM );
     235         315 :         speechLookAhead = &( st->speech_enc_pe[L_frame] );
     236             : 
     237             :         /* lsf concealment simulation */
     238         315 :         getConcealedLP( hPlc_Ext, AqCon, lsfBase, st->sr_core, st->clas, L_frame );
     239             : 
     240             :         /* apply encoder side PLC simulation */
     241         315 :         hPlc_Ext->pit_min = st->pit_min;
     242         315 :         hPlc_Ext->pit_max = st->pit_max;
     243         315 :         coderLookAheadInnovation( AqCon, &( hPlc_Ext->T0 ), hPlc_Ext, speechLookAhead, old_exc, L_SUBFR, st->L_frame );
     244             :     }
     245             : 
     246        1250 :     return;
     247             : }
     248             : 
     249             : /*-------------------------------------------------------------------*
     250             :  * GplcTcxEncSetup()
     251             :  *
     252             :  *
     253             :  *-------------------------------------------------------------------*/
     254             : 
     255         646 : void GplcTcxEncSetup(
     256             :     const int16_t tcxltp_pitch_int,
     257             :     PLC_ENC_EVS_HANDLE hPlc_Ext )
     258             : {
     259         646 :     hPlc_Ext->T0_4th = tcxltp_pitch_int;
     260             : 
     261         646 :     return;
     262             : }
     263             : 
     264             : /*-------------------------------------------------------------------*
     265             :  * encSideSpecPowDiffuseDetector()
     266             :  *
     267             :  *
     268             :  *-------------------------------------------------------------------*/
     269             : 
     270         604 : int16_t encSideSpecPowDiffuseDetector(
     271             :     float *lsf_ref,
     272             :     float *lsf_con,
     273             :     const int32_t sr_core,
     274             :     float *prev_lsf4_mean,
     275             :     const int16_t sw,
     276             :     const int16_t coder_type )
     277             : {
     278             :     float lsf_mod[M];
     279             :     float dist1, dist2, cum_dist1, cum_dist2;
     280             :     float lsf4_mean;
     281             :     float th;
     282             :     float th_dif_lsf4_mean;
     283             :     int16_t idx;
     284             :     int16_t cnt_imprv, i;
     285             : 
     286             :     /* calculate the mean of the lowest 4 lsfs */
     287         604 :     lsf4_mean = 0;
     288             : 
     289        3020 :     for ( i = 0; i < 4; i++ )
     290             :     {
     291        2416 :         lsf4_mean += lsf_ref[i];
     292             :     }
     293         604 :     lsf4_mean /= 4.0f;
     294             : 
     295         604 :     if ( sw )
     296             :     {
     297         604 :         mvr2r( lsf_con, lsf_mod, M );
     298             : 
     299         604 :         modify_lsf( lsf_mod, M, sr_core, 1 );
     300             : 
     301         604 :         cum_dist1 = 0;
     302         604 :         cum_dist2 = 0;
     303             : 
     304         604 :         cnt_imprv = 0;
     305             : 
     306             : 
     307       10268 :         for ( i = 0; i < M; i++ )
     308             :         {
     309        9664 :             dist1 = ( lsf_con[i] - lsf_ref[i] ) * ( lsf_con[i] - lsf_ref[i] );
     310        9664 :             dist2 = ( lsf_mod[i] - lsf_ref[i] ) * ( lsf_mod[i] - lsf_ref[i] );
     311        9664 :             cum_dist1 += dist1;
     312        9664 :             cum_dist2 += dist2;
     313             : 
     314        9664 :             if ( dist1 > dist2 )
     315             :             {
     316         631 :                 cnt_imprv++;
     317             :             }
     318             :         }
     319             : 
     320         604 :         th = 800;
     321         604 :         th_dif_lsf4_mean = 90;
     322             : 
     323         604 :         if ( sr_core == INT_FS_16k )
     324             :         {
     325         604 :             th *= 1.25;
     326         604 :             th_dif_lsf4_mean *= 1.25;
     327             :         }
     328             : 
     329             : 
     330         604 :         if ( cum_dist1 > cum_dist2 * 1.15 && lsf4_mean - *prev_lsf4_mean > th_dif_lsf4_mean && *prev_lsf4_mean < th && cnt_imprv > 2 && coder_type == GENERIC )
     331             :         {
     332           4 :             idx = 1;
     333             :         }
     334             :         else
     335             :         {
     336         600 :             idx = 0;
     337             :         }
     338             :     }
     339             :     else
     340             :     {
     341           0 :         idx = 0;
     342             :     }
     343             : 
     344             :     /* update parameters */
     345         604 :     *prev_lsf4_mean = lsf4_mean;
     346             : 
     347         604 :     return idx;
     348             : }
     349             : 
     350             : /*-------------------------------------------------------------------*
     351             :  * updateSpecPowDiffuseIdx()
     352             :  *
     353             :  *
     354             :  *-------------------------------------------------------------------*/
     355             : 
     356         604 : void updateSpecPowDiffuseIdx(
     357             :     const float gain_pitch_buf[], /* i  : gain pitch values   */
     358             :     const float gain_code_buf[],  /* i  : gain pitch values   */
     359             :     int16_t glr_idx[2],           /* o  : */
     360             :     float mean_gc[2]              /* o  : */
     361             : )
     362             : {
     363             :     float min_gp;
     364             :     int16_t k;
     365             : 
     366         604 :     mean_gc[1] = gain_code_buf[0];
     367         604 :     min_gp = gain_pitch_buf[0];
     368             : 
     369        2416 :     for ( k = 1; k < 4; k++ )
     370             :     {
     371        1812 :         mean_gc[1] += gain_code_buf[k];
     372             : 
     373        1812 :         if ( gain_pitch_buf[k] < min_gp )
     374             :         {
     375         679 :             min_gp = gain_pitch_buf[k];
     376             :         }
     377             :     }
     378             : 
     379         604 :     if ( mean_gc[1] / ( mean_gc[0] + 1e-6 ) < 1.098 || min_gp > 0.82 )
     380             :     {
     381         423 :         glr_idx[0] = 0;
     382             :     }
     383         604 :     mean_gc[0] = mean_gc[1];
     384             : 
     385         604 :     return;
     386             : }

Generated by: LCOV version 1.14