LCOV - code coverage report
Current view: top level - lib_dec - waveadjust_fec_dec.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 0 324 0.0 %
Date: 2025-05-23 08:37:30 Functions: 0 16 0.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 "wmc_auto.h"
      45             : 
      46             : 
      47             : /*-------------------------------------------------------------------*
      48             :  * Local functions
      49             :  *
      50             :  *-------------------------------------------------------------------*/
      51             : 
      52           0 : static void LpFilter2(
      53             :     const float *x,
      54             :     float *y,
      55             :     const int16_t N,
      56             :     float *mem )
      57             : {
      58             :     int16_t i;
      59             : 
      60           0 :     y[0] = 0.18f * mem[0] + 0.64f * mem[1] + 0.18f * x[0];
      61           0 :     y[1] = 0.18f * mem[1] + 0.64f * y[0] + 0.18f * x[1];
      62             : 
      63           0 :     for ( i = 2; i < N; i++ )
      64             :     {
      65           0 :         y[i] = 0.18f * y[i - 2] + 0.64f * y[i - 1] + 0.18f * x[i];
      66             :     }
      67             : 
      68           0 :     return;
      69             : }
      70             : 
      71           0 : static float harmo(
      72             :     const float *X,
      73             :     const int16_t n,
      74             :     const float f )
      75             : {
      76           0 :     int16_t h, k, m = 8;
      77           0 :     float ener = 0, ener_harmo = 0;
      78             : 
      79           0 :     for ( k = 1; k < m + 1; k++ )
      80             :     {
      81           0 :         h = (int16_t) ( k * f - 0.5f );
      82           0 :         if ( k * f - h > 0.5f )
      83             :         {
      84           0 :             ener_harmo += X[h] * X[h] + X[h + 1] * X[h + 1];
      85             :         }
      86             :         else
      87             :         {
      88           0 :             ener_harmo += X[h] * X[h];
      89             :         }
      90             :     }
      91             : 
      92           0 :     for ( k = 0; k < n; k++ )
      93             :     {
      94           0 :         ener += X[k] * X[k];
      95             :     }
      96             : 
      97           0 :     return ener_harmo / ( ener + EPSILON );
      98             : }
      99             : 
     100             : 
     101           0 : static int16_t Is_Periodic(
     102             :     const float cov_max,
     103             :     const int16_t zp,
     104             :     const float ener,
     105             :     const float ener_mean,
     106             :     const int16_t pitch,
     107             :     const int16_t L_frameTCX,
     108             :     const float *mdctdata )
     109             : {
     110           0 :     int16_t flag = 0;
     111           0 :     float f = 2.0f * L_frameTCX / pitch;
     112             :     float harm;
     113             : 
     114           0 :     harm = harmo( mdctdata /*X*/, L_frameTCX, f );
     115             : 
     116           0 :     if ( ener < 50 || ( ener < ener_mean - 8.0f && cov_max < 0.9f ) )
     117             :     {
     118           0 :         flag = 0;
     119             :     }
     120           0 :     else if ( cov_max > 0.8f )
     121             :     {
     122           0 :         flag = 1;
     123             :     }
     124           0 :     else if ( zp > 100 )
     125             :     {
     126           0 :         flag = 0;
     127             :     }
     128           0 :     else if ( ener < ener_mean - 6 )
     129             :     {
     130           0 :         flag = 0;
     131             :     }
     132           0 :     else if ( ener > ener_mean + 1 && cov_max > 0.6f )
     133             :     {
     134           0 :         flag = 1;
     135             :     }
     136           0 :     else if ( harm < 0.7f )
     137             :     {
     138           0 :         flag = 0;
     139             :     }
     140             :     else
     141             :     {
     142           0 :         flag = 1;
     143             :     }
     144             : 
     145           0 :     return flag;
     146             : }
     147             : 
     148             : 
     149           0 : static int16_t zero_pass(
     150             :     const float *s,
     151             :     const int16_t N )
     152             : {
     153           0 :     int16_t zp = 0, i;
     154             : 
     155           0 :     for ( i = 1; i < N; i++ )
     156             :     {
     157           0 :         if ( s[i - 1] * s[i] <= 0 )
     158             :         {
     159           0 :             zp++;
     160             :         }
     161             :     }
     162             : 
     163           0 :     return zp;
     164             : }
     165             : 
     166             : 
     167           0 : static float sig_tilt(
     168             :     const float *s,
     169             :     const int16_t L_frameTCX )
     170             : {
     171             :     float tilt, enr1, enr2;
     172           0 :     int16_t L_subfr, shift = 2;
     173             :     const float *p1, *p2;
     174             : 
     175           0 :     L_subfr = L_frameTCX >> 2;
     176           0 :     p1 = s + L_subfr;
     177           0 :     p2 = s + L_subfr - shift;
     178           0 :     enr1 = dotp( p1, p2, L_frameTCX - L_subfr );
     179           0 :     enr2 = dotp( p1, p1, L_frameTCX - L_subfr );
     180           0 :     tilt = enr1 / ( enr2 + EPSILON );
     181             : 
     182           0 :     return tilt;
     183             : }
     184             : 
     185             : 
     186           0 : static int16_t pitch_search(
     187             :     float *s, /* lastPcmOut */
     188             :     float *outx_new,
     189             :     const int16_t L_frameTCX,
     190             :     float *voicing,
     191             :     int16_t *zp,
     192             :     float *ener,
     193             :     float ener_mean,
     194             :     float *mdct_data,
     195             :     const int16_t core )
     196             : {
     197             :     int16_t pitch, t, i;
     198             :     float cov_max, temp, tmp, tilt, mdct_ener, low_freq_rate;
     199             :     float s_LP[L_FRAME_MAX];
     200             :     float s_tmp[L_FRAME_MAX];
     201             :     int16_t L_frameTCX_tmp;
     202             :     int16_t pitch_tmp[3];
     203             :     float mem[2];
     204             :     int16_t start_pos, end_pos;
     205             :     int16_t cov_size;
     206             :     int16_t flag, zp_current;
     207             :     int16_t curr_frmsize;
     208             :     float tmp_last;
     209             :     float cov_max_tmp;
     210             :     float temp2, voicing2;
     211             : 
     212           0 :     set_f( s_LP, 0, L_FRAME_MAX );
     213           0 :     mem[0] = 0.0f;
     214           0 :     mem[1] = 0.0f;
     215           0 :     tmp_last = 0;
     216           0 :     cov_max_tmp = 0;
     217           0 :     flag = 0;
     218             : 
     219           0 :     curr_frmsize = L_frameTCX;
     220           0 :     if ( core == TCX_10_CORE )
     221             :     {
     222           0 :         curr_frmsize = L_frameTCX >> 1;
     223             :     }
     224             : 
     225           0 :     zp_current = zero_pass( outx_new, curr_frmsize );
     226           0 :     if ( core == TCX_10_CORE )
     227             :     {
     228           0 :         zp_current = zp_current << 1;
     229             :     }
     230             : 
     231           0 :     if ( L_frameTCX <= L_FRAME )
     232             :     {
     233           0 :         if ( zp_current > 70 )
     234             :         {
     235           0 :             return 0;
     236             :         }
     237             :     }
     238             :     else
     239             :     {
     240           0 :         if ( zp_current > 105 )
     241             :         {
     242           0 :             return 0;
     243             :         }
     244             :     }
     245             : 
     246           0 :     t = 30;
     247           0 :     if ( core == TCX_10_CORE )
     248             :     {
     249           0 :         t = 30 / 2;
     250           0 :         mdct_data = mdct_data + curr_frmsize;
     251             :     }
     252             : 
     253           0 :     mdct_ener = 0;
     254           0 :     for ( i = 0; i < t; i++ )
     255             :     {
     256           0 :         mdct_ener += mdct_data[i] * mdct_data[i];
     257             :     }
     258           0 :     low_freq_rate = mdct_ener;
     259           0 :     for ( ; i < curr_frmsize; i++ )
     260             :     {
     261           0 :         mdct_ener += mdct_data[i] * mdct_data[i];
     262             :     }
     263           0 :     low_freq_rate /= ( mdct_ener + EPSILON );
     264             : 
     265           0 :     if ( core == TCX_10_CORE )
     266             :     {
     267           0 :         mdct_data = mdct_data - curr_frmsize;
     268             :     }
     269             : 
     270           0 :     if ( low_freq_rate < 0.02f )
     271             :     {
     272           0 :         return 0;
     273             :     }
     274             : 
     275           0 :     LpFilter2( s, s_LP, L_frameTCX, mem );
     276             : 
     277           0 :     tilt = sig_tilt( s_LP, L_frameTCX );
     278             : 
     279           0 :     if ( L_frameTCX <= L_FRAME16k )
     280             :     {
     281           0 :         if ( tilt < 0.5f )
     282             :         {
     283           0 :             return 0;
     284             :         }
     285             :     }
     286             :     else
     287             :     {
     288           0 :         if ( tilt < 0.7f )
     289             :         {
     290           0 :             return 0;
     291             :         }
     292             :     }
     293             : 
     294           0 :     cov_max = 0;
     295           0 :     pitch = 0;
     296           0 :     if ( L_frameTCX <= L_FRAME16k )
     297             :     {
     298           0 :         start_pos = (int16_t) ( L_frameTCX * 34 / 256.0 + 0.5f );
     299           0 :         end_pos = (int16_t) ( L_frameTCX * 3 / 4.0 + 0.5f );
     300           0 :         for ( t = start_pos; t < end_pos; t++ )
     301             :         {
     302           0 :             cov_size = L_frameTCX - t;
     303           0 :             tmp = dotp( s_LP, s_LP + t, cov_size ) / cov_size;
     304           0 :             if ( t > start_pos ) /* don't use the first value */
     305             :             {
     306           0 :                 if ( tmp > tmp_last ) /* store the current cov, if it is larger than the last one */
     307             :                 {
     308           0 :                     cov_max_tmp = tmp;
     309             :                 }
     310           0 :                 else if ( cov_max < cov_max_tmp ) /* otherwise */
     311             :                 {
     312           0 :                     cov_max = cov_max_tmp; /* use the last value cov, being a max */
     313           0 :                     pitch = t - 1;         /* and the last index as pitch */
     314             :                 }
     315             :             }
     316           0 :             tmp_last = tmp;
     317             :         }
     318             : 
     319           0 :         temp = (float) ( sqrt( dotp( s_LP + pitch, s_LP + pitch, L_frameTCX - pitch ) ) * sqrt( dotp( s_LP, s_LP, L_frameTCX - pitch ) ) );
     320             : 
     321           0 :         *voicing = cov_max * ( L_frameTCX - pitch ) / ( temp + EPSILON );
     322             : 
     323           0 :         temp2 = (float) ( sqrt( dotp( s_LP + ( pitch >> 1 ), s_LP + ( pitch >> 1 ), L_frameTCX - ( pitch >> 1 ) ) ) * sqrt( dotp( s_LP, s_LP, L_frameTCX - ( pitch >> 1 ) ) ) );
     324             : 
     325           0 :         voicing2 = dotp( s_LP + ( pitch >> 1 ), s_LP, L_frameTCX - ( pitch >> 1 ) ) / temp2;
     326             : 
     327           0 :         if ( voicing2 > *voicing )
     328             :         {
     329           0 :             pitch = pitch >> 1;
     330           0 :             *voicing = voicing2;
     331             :         }
     332             :     }
     333             :     else
     334             :     {
     335           0 :         L_frameTCX_tmp = L_frameTCX >> 1;
     336             : 
     337           0 :         for ( i = 0; i < L_frameTCX_tmp; i++ )
     338             :         {
     339           0 :             s_tmp[i] = s_LP[2 * i];
     340             :         }
     341             : 
     342           0 :         start_pos = (int16_t) ( ( 34.0f * L_frameTCX_tmp ) / L_FRAME + 0.5f );
     343           0 :         end_pos = (int16_t) ( ( L_frameTCX_tmp >> 1 ) * 1.5f + 0.5f );
     344           0 :         for ( t = start_pos; t < end_pos; t++ )
     345             :         {
     346           0 :             cov_size = L_frameTCX_tmp - t;
     347           0 :             tmp = dotp( s_tmp, s_tmp + t, cov_size ) / cov_size;
     348             : 
     349           0 :             if ( t > start_pos ) /* don't use the first value */
     350             :             {
     351           0 :                 if ( tmp > tmp_last ) /* store the current cov, if it is larger than the last one */
     352             :                 {
     353           0 :                     cov_max_tmp = tmp;
     354             :                 }
     355           0 :                 else if ( cov_max < cov_max_tmp ) /* otherwise */
     356             :                 {
     357           0 :                     cov_max = cov_max_tmp; /* use the last value cov, being a max */
     358           0 :                     pitch = t - 1;         /* and the last index as pitch */
     359             :                 }
     360             :             }
     361             : 
     362           0 :             tmp_last = tmp;
     363             :         }
     364             : 
     365           0 :         if ( pitch > 0 )
     366             :         {
     367           0 :             pitch_tmp[0] = max( 2 * pitch - 1, 0 );
     368           0 :             pitch_tmp[1] = 2 * pitch;
     369           0 :             pitch_tmp[2] = 2 * pitch + 1;
     370           0 :             cov_max = 0;
     371           0 :             pitch = 0;
     372             : 
     373           0 :             for ( i = 0; i < 3; i++ )
     374             :             {
     375           0 :                 cov_size = L_frameTCX - pitch_tmp[i];
     376             : 
     377           0 :                 temp = (float) ( sqrt( dotp( s_LP + pitch_tmp[i], s_LP + pitch_tmp[i], cov_size ) ) * sqrt( dotp( s_LP, s_LP, cov_size ) ) );
     378             : 
     379           0 :                 tmp = dotp( s_LP, s_LP + pitch_tmp[i], cov_size ) / ( temp + EPSILON );
     380             : 
     381           0 :                 if ( tmp > cov_max )
     382             :                 {
     383           0 :                     cov_max = tmp;
     384           0 :                     pitch = pitch_tmp[i];
     385             :                 }
     386             :             }
     387             : 
     388           0 :             *voicing = cov_max;
     389             :         }
     390             :     }
     391             : 
     392           0 :     if ( pitch > 0 )
     393             :     {
     394           0 :         flag = Is_Periodic( *voicing, *zp, *ener, ener_mean, pitch, L_frameTCX, mdct_data );
     395             :     }
     396             : 
     397           0 :     if ( flag == 0 )
     398             :     {
     399           0 :         pitch = 0;
     400             :     }
     401             : 
     402           0 :     return pitch;
     403             : }
     404             : 
     405             : 
     406           0 : static int16_t OverlapAdd(
     407             :     float *pitch125_data,
     408             :     float *sbuf,
     409             :     const int16_t n,
     410             :     const int16_t pitch,
     411             :     const int16_t Bufsize )
     412             : {
     413           0 :     int16_t pitch125 = (int16_t) floor( 0.5f + ( 1.25f * (float) pitch ) );
     414           0 :     int16_t Loverlap = pitch125 - pitch;
     415           0 :     int16_t n1 = min( Loverlap, Bufsize - n );
     416           0 :     int16_t n2 = min( pitch125, Bufsize - n );
     417             :     int16_t i;
     418             :     float tmp, dat;
     419             : 
     420           0 :     for ( i = 0; i < n1; i++ )
     421             :     {
     422           0 :         tmp = (float) i / (float) Loverlap;
     423           0 :         dat = sbuf[n + i];
     424           0 :         sbuf[n + i] = (float) ( ( 1.0 - tmp ) * dat + tmp * pitch125_data[i] );
     425             :     }
     426             : 
     427           0 :     for ( i = n1; i < n2; i++ )
     428             :     {
     429           0 :         sbuf[n + i] = pitch125_data[i];
     430             :     }
     431             : 
     432           0 :     return ( n + pitch );
     433             : }
     434             : 
     435             : 
     436           0 : static void add_noise(
     437             :     float *sbuf,
     438             :     float *outx_new_n1,
     439             :     float *noise_seg,
     440             :     const int16_t Len,
     441             :     float *gain,
     442             :     const float *gain_n,
     443             :     const int16_t firstFrame )
     444             : {
     445             :     int16_t i;
     446             : 
     447           0 :     if ( !firstFrame )
     448             :     {
     449           0 :         sbuf[0] += *gain * ( noise_seg[0] - 0.68f * ( *outx_new_n1 ) );
     450           0 :         *gain = 0.99f * ( *gain ) + 0.01f * ( *gain_n );
     451             :     }
     452           0 :     for ( i = 1; i < Len; i++ )
     453             :     {
     454           0 :         sbuf[i] += *gain * ( noise_seg[i] - 0.68f * noise_seg[i - 1] );
     455           0 :         *gain = 0.99f * ( *gain ) + 0.01f * ( *gain_n );
     456             :     }
     457           0 :     *outx_new_n1 = noise_seg[i - 1];
     458             : 
     459           0 :     return;
     460             : }
     461             : 
     462           0 : static int16_t waveform_adj(
     463             :     T_PLCInfo_HANDLE hPlcInfo,
     464             :     float *overlapbuf,
     465             :     float *outdata2,
     466             :     float *outx_new,
     467             :     const int16_t L_frameTCX,
     468             :     const float voicing,
     469             :     const int16_t core )
     470             : {
     471             :     int16_t i, i1, i2, zp1, zp2, pitch;
     472             :     float sbuf[L_FRAME_MAX];
     473             :     float tmp_buf[L_FRAME_MAX], *p_tmp;
     474             :     int16_t pitch125, Loverlap, n;
     475             :     float pitch125_data[L_FRAME_MAX];
     476             : 
     477           0 :     set_f( sbuf, 0, L_FRAME_MAX );
     478           0 :     set_f( tmp_buf, 0, L_FRAME_MAX );
     479           0 :     set_f( pitch125_data, 0, L_FRAME_MAX );
     480             : 
     481           0 :     zp1 = zero_pass( outdata2, L_frameTCX >> 1 );
     482           0 :     zp2 = zero_pass( outdata2 + ( L_frameTCX >> 1 ), L_frameTCX >> 1 );
     483             : 
     484           0 :     pitch = hPlcInfo->Pitch;
     485             : 
     486             :     /* judge if the pitch is usable */
     487           0 :     if ( 4 * max( zp1, 1 ) < zp2 )
     488             :     {
     489           0 :         return 0;
     490             :     }
     491             : 
     492             :     /* adjust the pitch value */
     493           0 :     if ( hPlcInfo->T_bfi && pitch <= L_frameTCX >> 1 && L_frameTCX > L_FRAME && core == TCX_20_CORE )
     494             :     {
     495           0 :         i1 = 1 + maximum( outx_new, pitch, NULL );
     496           0 :         i2 = 1 + maximum( outx_new + pitch, pitch, NULL );
     497           0 :         if ( (float) ( i2 + pitch - i1 ) < ( 1.25f * pitch ) && ( 1.25f * ( i2 + pitch - i1 ) ) > (float) pitch && (float) ( i2 + pitch - i1 ) < (float) ( L_frameTCX >> 1 ) )
     498             :         {
     499           0 :             pitch = i2 + pitch - i1;
     500             :         }
     501             :     }
     502             : 
     503           0 :     pitch125 = (int16_t) floor( 0.5f + ( 1.25f * (float) pitch ) );
     504           0 :     Loverlap = pitch125 - pitch;
     505           0 :     mvr2r( outdata2 + L_frameTCX - pitch, pitch125_data, pitch );
     506           0 :     mvr2r( outx_new, pitch125_data + pitch, Loverlap );
     507           0 :     mvr2r( outx_new, sbuf, L_frameTCX );
     508             : 
     509           0 :     p_tmp = tmp_buf + 1;
     510           0 :     mvr2r( pitch125_data, p_tmp, pitch125 );
     511           0 :     p_tmp[-1] = outdata2[L_frameTCX - pitch - 1];
     512           0 :     p_tmp[pitch125] = outx_new[Loverlap];
     513           0 :     for ( i = 0; i < pitch125; i++ )
     514             :     {
     515           0 :         pitch125_data[i] = 0.18f * p_tmp[i - 1] + 0.64f * p_tmp[i] + 0.18f * p_tmp[i + 1];
     516             :     }
     517             : 
     518           0 :     n = 0;
     519           0 :     while ( n < L_frameTCX ) /* periodical extension */
     520             :     {
     521           0 :         n = OverlapAdd( pitch125_data, sbuf, n, pitch, L_frameTCX );
     522             :     }
     523             : 
     524             :     /* maximum pitch lag is 3/4 L_frameTCX; pitch125_data is reused for
     525             :        temporary storage, since outdata2 (holding the pcm data of the
     526             :        last good frame) is still needed and overlapbuf overlaps outdata2 */
     527           0 :     mvr2r( &sbuf[L_frameTCX / 4], pitch125_data, ( 3 * L_frameTCX ) / 4 );
     528             : 
     529           0 :     hPlcInfo->nsapp_gain = 0.0;
     530           0 :     hPlcInfo->nsapp_gain_n = 1.0f - voicing / 2;
     531             : 
     532             :     /* use last good signal for noise generation */
     533           0 :     add_noise( sbuf, &( hPlcInfo->outx_new_n1 ), outdata2, L_frameTCX, &( hPlcInfo->nsapp_gain ), &( hPlcInfo->nsapp_gain_n ), 1 );
     534             : 
     535             :     /* save current (noisy) output from IMDCT */
     536           0 :     mvr2r( outx_new, hPlcInfo->data_noise, L_frameTCX );
     537             : 
     538             :     /* overlapbuf can now be filled with sbuf, needed for subsequently lost frames */
     539           0 :     mvr2r( pitch125_data, &overlapbuf[L_frameTCX / 4], ( 3 * L_frameTCX ) / 4 );
     540             : 
     541           0 :     for ( i = 0; i < L_frameTCX; i++ )
     542             :     {
     543           0 :         outx_new[i] = sbuf[i];
     544             :     }
     545             : 
     546           0 :     return pitch;
     547             : }
     548             : 
     549             : 
     550             : /*-------------------------------------------------------------------*
     551             :  * waveform_adj2()
     552             :  *
     553             :  *-------------------------------------------------------------------*/
     554             : 
     555           0 : void waveform_adj2(
     556             :     T_PLCInfo_HANDLE hPlcInfo,
     557             :     float *overlapbuf,
     558             :     float *outx_new,
     559             :     const int16_t delay,
     560             :     const int16_t bfi_cnt,
     561             :     const int16_t bfi )
     562             : {
     563           0 :     int16_t i, n = 0;
     564             :     float ratio;
     565             :     float sbuf[L_FRAME_MAX];
     566             :     int16_t pitch, L_frameTCX;
     567             : 
     568           0 :     pitch = hPlcInfo->Pitch;
     569           0 :     L_frameTCX = hPlcInfo->L_frameTCX;
     570             : 
     571           0 :     if ( pitch > 0 )
     572             :     {
     573           0 :         while ( n < L_frameTCX )
     574             :         {
     575             :             /* periodical extension */
     576           0 :             for ( i = 0; i < min( pitch, L_frameTCX - n ); i++ )
     577             :             {
     578           0 :                 sbuf[n + i] = overlapbuf[L_frameTCX - pitch + i];
     579             :             }
     580           0 :             n += pitch;
     581             :         }
     582           0 :         for ( i = 0; i < L_frameTCX; i++ )
     583             :         {
     584           0 :             overlapbuf[i] = sbuf[i];
     585             :         }
     586             : 
     587             :         /* use last (noisy) output from IMDCT for noise generation */
     588           0 :         add_noise( sbuf, &( hPlcInfo->outx_new_n1 ), hPlcInfo->data_noise, L_frameTCX, &( hPlcInfo->nsapp_gain ), &( hPlcInfo->nsapp_gain_n ), 0 );
     589             : 
     590           0 :         if ( bfi )
     591             :         {
     592             :             /* save current (noisy) output from IMDCT */
     593           0 :             mvr2r( outx_new, hPlcInfo->data_noise, L_frameTCX );
     594             :         }
     595             : 
     596           0 :         if ( bfi_cnt == 4 || bfi == 0 )
     597             :         {
     598           0 :             if ( bfi == 0 )
     599             :             {
     600           0 :                 int16_t gain_zero_start = 10000;
     601             :                 /* overlap-and-add */
     602           0 :                 if ( hPlcInfo->step_concealgain > EPSILON )
     603             :                 {
     604           0 :                     gain_zero_start = (int16_t) min( (float) L_FRAME48k, ( hPlcInfo->recovery_gain / hPlcInfo->step_concealgain ) ) + 1;
     605             :                 }
     606             : 
     607           0 :                 if ( delay > 0 )
     608             :                 {
     609           0 :                     L_frameTCX -= delay;
     610             :                 }
     611           0 :                 for ( i = 0; i < min( gain_zero_start, L_frameTCX ); i++ )
     612             :                 {
     613           0 :                     ratio = (float) i / (float) L_frameTCX;
     614           0 :                     outx_new[i] = ( 1 - ratio ) * sbuf[i] * hPlcInfo->recovery_gain + ratio * outx_new[i];
     615           0 :                     hPlcInfo->recovery_gain -= hPlcInfo->step_concealgain;
     616             :                 }
     617           0 :                 for ( i = gain_zero_start; i < L_frameTCX; i++ )
     618             :                 {
     619           0 :                     ratio = (float) i / (float) L_frameTCX;
     620           0 :                     outx_new[i] = ratio * outx_new[i];
     621             :                 }
     622           0 :                 if ( hPlcInfo->recovery_gain < 0.0f )
     623             :                 {
     624           0 :                     hPlcInfo->recovery_gain = 0.0f;
     625             :                 }
     626             :             }
     627             :             else
     628             :             {
     629             :                 /* overlap-and-add */
     630           0 :                 for ( i = 0; i < L_frameTCX; i++ )
     631             :                 {
     632           0 :                     ratio = (float) i / (float) L_frameTCX;
     633           0 :                     outx_new[i] = ( 1 - ratio ) * sbuf[i] + ratio * outx_new[i];
     634             :                 }
     635             :             }
     636             :         }
     637             :         else
     638             :         {
     639           0 :             mvr2r( sbuf, outx_new, L_frameTCX );
     640             :         }
     641             :     }
     642             : 
     643           0 :     return;
     644             : }
     645             : 
     646             : 
     647             : /*-------------------------------------------------------------------*
     648             :  * set_state()
     649             :  *
     650             :  *
     651             :  *-------------------------------------------------------------------*/
     652             : 
     653           0 : void set_state(
     654             :     int16_t *state,
     655             :     const int16_t num,
     656             :     const int16_t N )
     657             : {
     658             :     int16_t i;
     659             : 
     660           0 :     for ( i = 0; i < N - 1; i++ )
     661             :     {
     662           0 :         state[i] = state[i + 1];
     663             :     }
     664           0 :     state[N - 1] = num;
     665             : 
     666           0 :     return;
     667             : }
     668             : 
     669             : 
     670             : /*-------------------------------------------------------------------*
     671             :  * concealment_init()
     672             :  *
     673             :  *
     674             :  *-------------------------------------------------------------------*/
     675             : 
     676           0 : void concealment_init(
     677             :     const int16_t L_frameTCX,
     678             :     T_PLCInfo_HANDLE hPlcInfo )
     679             : {
     680             :     int16_t i;
     681             : 
     682           0 :     hPlcInfo->L_frameTCX = L_frameTCX;
     683           0 :     hPlcInfo->Pitch = 0;
     684           0 :     hPlcInfo->T_bfi = 0;
     685           0 :     hPlcInfo->outx_new_n1 = 0.0f;
     686           0 :     hPlcInfo->nsapp_gain = 0.0f;
     687           0 :     hPlcInfo->nsapp_gain_n = 0.0f;
     688           0 :     hPlcInfo->ener_mean = 59.4260f;
     689           0 :     hPlcInfo->ener = 0.0f;
     690           0 :     hPlcInfo->zp = L_frameTCX;
     691           0 :     hPlcInfo->recovery_gain = 0.0f;
     692           0 :     hPlcInfo->step_concealgain = 0.0f;
     693           0 :     hPlcInfo->concealment_method = TCX_NONTONAL;
     694           0 :     hPlcInfo->subframe = 0;
     695           0 :     hPlcInfo->nbLostCmpt = 0;
     696           0 :     hPlcInfo->seed = RANDOM_INITSEED;
     697             : 
     698           0 :     for ( i = 0; i < TCX_TONALITY_INIT_CNT; i++ )
     699             :     {
     700           0 :         hPlcInfo->TCX_Tonality[i] = 1;
     701             :     }
     702           0 :     for ( i = TCX_TONALITY_INIT_CNT; i < DEC_STATE_LEN; i++ )
     703             :     {
     704           0 :         hPlcInfo->TCX_Tonality[i] = 0;
     705             :     }
     706           0 :     for ( i = 0; i < MAX_POST_LEN; i++ )
     707             :     {
     708           0 :         hPlcInfo->Transient[i] = 1;
     709             :     }
     710             : 
     711           0 :     for ( i = 0; i < L_FRAME_MAX; i++ )
     712             :     {
     713           0 :         hPlcInfo->data_reci2[i] = 0;
     714             :     }
     715             : 
     716           0 :     return;
     717             : }
     718             : 
     719             : 
     720             : /*-------------------------------------------------------------------*
     721             :  * concealment_decode()
     722             :  *
     723             :  *
     724             :  *-------------------------------------------------------------------*/
     725             : 
     726           0 : void concealment_decode(
     727             :     const int16_t core,
     728             :     float *invkoef,
     729             :     T_PLCInfo_HANDLE hPlcInfo )
     730             : {
     731             :     int16_t i;
     732           0 :     int16_t *seed = &( hPlcInfo->seed );
     733             :     int16_t sign;
     734             : 
     735           0 :     if ( hPlcInfo->concealment_method == TCX_NONTONAL )
     736             :     {
     737           0 :         if ( core == TCX_20_CORE )
     738             :         {
     739             :             /* copy the data of the last frame */
     740           0 :             mvr2r( hPlcInfo->data_reci2, invkoef, hPlcInfo->L_frameTCX );
     741             : 
     742             :             /* sign randomization */
     743           0 :             for ( i = 0; i < hPlcInfo->L_frameTCX; i++ )
     744             :             {
     745             :                 int16_t rnd;
     746           0 :                 rnd = own_random( seed );
     747           0 :                 sign = ( rnd >= 0 ) - ( rnd < 0 );
     748           0 :                 invkoef[i] *= sign;
     749             :             }
     750             :         }
     751             :     }
     752             : 
     753           0 :     return;
     754             : }
     755             : 
     756             : 
     757             : /*-------------------------------------------------------------------*
     758             :  * concealment_update()
     759             :  *
     760             :  *
     761             :  *-------------------------------------------------------------------*/
     762             : 
     763           0 : void concealment_update(
     764             :     const int16_t bfi,
     765             :     const int16_t core,
     766             :     const int16_t tonality,
     767             :     float *invkoef,
     768             :     T_PLCInfo_HANDLE hPlcInfo )
     769             : {
     770           0 :     float *data_reci2 = hPlcInfo->data_reci2;
     771           0 :     int16_t subframe = hPlcInfo->subframe;
     772             :     int16_t i;
     773             : 
     774           0 :     if ( core == TCX_20_CORE )
     775             :     {
     776           0 :         set_state( hPlcInfo->Transient, core, MAX_POST_LEN );
     777             : 
     778           0 :         for ( i = 0; i < hPlcInfo->L_frameTCX; i++ )
     779             :         {
     780           0 :             data_reci2[i] = invkoef[i];
     781             :         }
     782             : 
     783           0 :         if ( !bfi )
     784             :         {
     785           0 :             set_state( hPlcInfo->TCX_Tonality, tonality, DEC_STATE_LEN );
     786             :         }
     787             :     }
     788             :     else
     789             :     {
     790           0 :         if ( subframe == 0 )
     791             :         {
     792           0 :             set_state( hPlcInfo->Transient, core, MAX_POST_LEN );
     793             : 
     794           0 :             if ( !bfi )
     795             :             {
     796           0 :                 set_state( hPlcInfo->TCX_Tonality, tonality, DEC_STATE_LEN );
     797             :             }
     798             :         }
     799             :         /* don't store the second subframe during frameloss; in
     800             :            pitch_search(), low_freq_rate is derived on the last good
     801             :            TCX-10 spectrum */
     802           0 :         if ( !bfi || subframe == 0 )
     803             :         {
     804           0 :             float *ptr = data_reci2 + subframe;
     805           0 :             for ( i = 0; i < ( hPlcInfo->L_frameTCX >> 1 ); i++ )
     806             :             {
     807           0 :                 ptr[i] = invkoef[i];
     808             :             }
     809             :         }
     810             :     }
     811           0 :     return;
     812             : }
     813             : 
     814             : 
     815             : /*-------------------------------------------------------------------*
     816             :  * concealment_update2()
     817             :  *
     818             :  *
     819             :  *-------------------------------------------------------------------*/
     820             : 
     821           0 : void concealment_update2(
     822             :     const float *outx_new,
     823             :     T_PLCInfo_HANDLE hPlcInfo,
     824             :     const int16_t L_frameTCX )
     825             : {
     826           0 :     hPlcInfo->zp = zero_pass( outx_new, L_frameTCX );
     827           0 :     hPlcInfo->ener = dotp( outx_new, outx_new, L_frameTCX ) / L_frameTCX;
     828           0 :     hPlcInfo->ener = 10 * (float) log10( hPlcInfo->ener + EPSILON );
     829             : 
     830           0 :     if ( hPlcInfo->zp < 100 && hPlcInfo->ener > 50 )
     831             :     {
     832           0 :         hPlcInfo->ener_mean = 0.98f * hPlcInfo->ener_mean + 0.02f * hPlcInfo->ener;
     833             :     }
     834             : 
     835           0 :     return;
     836             : }
     837             : 
     838             : 
     839             : /*-------------------------------------------------------------------*
     840             :  * concealment_signal_tuning()
     841             :  *
     842             :  *
     843             :  *-------------------------------------------------------------------*/
     844             : 
     845           0 : void concealment_signal_tuning(
     846             :     Decoder_State *st,
     847             :     const int16_t bfi,
     848             :     float *outx_new,
     849             :     const int16_t past_core )
     850             : {
     851           0 :     float voicing = 0;
     852           0 :     T_PLCInfo_HANDLE hPlcInfo = st->hPlcInfo;
     853           0 :     float *OverlapBuf = st->hTonalMDCTConc->secondLastPcmOut;
     854           0 :     float *outdata2 = st->hTonalMDCTConc->lastPcmOut;
     855             : 
     856           0 :     if ( bfi )
     857             :     {
     858           0 :         if ( st->enablePlcWaveadjust && hPlcInfo->concealment_method == TCX_NONTONAL )
     859             :         {
     860           0 :             if ( st->nbLostCmpt == 1 )
     861             :             {
     862           0 :                 hPlcInfo->Pitch = pitch_search( outdata2, outx_new, st->hPlcInfo->L_frameTCX, &voicing, &hPlcInfo->zp, &hPlcInfo->ener, hPlcInfo->ener_mean, st->hPlcInfo->data_reci2, st->core );
     863             : 
     864           0 :                 if ( hPlcInfo->Pitch ) /* waveform adjustment for the first lost frame */
     865             :                 {
     866           0 :                     hPlcInfo->Pitch = waveform_adj( hPlcInfo, OverlapBuf, outdata2, outx_new, st->hPlcInfo->L_frameTCX, voicing, st->core );
     867             :                 }
     868             :             }
     869           0 :             else if ( st->nbLostCmpt < 5 ) /* waveform adjustment for the 2nd~4th lost frame */
     870             :             {
     871           0 :                 waveform_adj2( hPlcInfo, OverlapBuf, outx_new, 0, st->nbLostCmpt, bfi );
     872             :             }
     873             :         }
     874           0 :         hPlcInfo->T_bfi = 1;
     875             :     }
     876             :     else
     877             :     {
     878           0 :         if ( st->prev_bfi && past_core != ACELP_CORE && st->last_total_brate >= HQ_48k && st->last_codec_mode == MODE2 )
     879             :         {
     880           0 :             if ( hPlcInfo->concealment_method == TCX_NONTONAL )
     881             :             {
     882           0 :                 if ( hPlcInfo->nbLostCmpt < 4 ) /* smoothing of the concealed signal with the good signal */
     883             :                 {
     884           0 :                     waveform_adj2( hPlcInfo, OverlapBuf, outx_new, 0, hPlcInfo->nbLostCmpt + 1, bfi );
     885             :                 }
     886             :             }
     887             :         }
     888             :         else
     889             :         {
     890           0 :             hPlcInfo->T_bfi = 0;
     891             :         }
     892             :     }
     893             : 
     894           0 :     return;
     895             : }

Generated by: LCOV version 1.14