LCOV - code coverage report
Current view: top level - lib_lc3plus - plc_tdc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 0 277 0.0 %
Date: 2025-05-23 08:37:30 Functions: 0 17 0.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             : *                        ETSI TS 103 634 V1.5.1                               *
       3             : *              Low Complexity Communication Codec Plus (LC3plus)              *
       4             : *                                                                             *
       5             : * Copyright licence is solely granted through ETSI Intellectual Property      *
       6             : * Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
       7             : * estoppel or otherwise.                                                      *
       8             : ******************************************************************************/
       9             : 
      10             : /***************************************************************************\
      11             :  *   contents/description: Main function for Time domain concealment
      12             : \***************************************************************************/
      13             : 
      14             : #include "options.h"
      15             : #include "wmc_auto.h"
      16             : #include <string.h>
      17             : #include "functions.h"
      18             : #include "constants.h"
      19             : 
      20             : static LC3_INT16 TDC_random_short(LC3_INT16 *seed);
      21             : static LC3_FLOAT TDC_get_gainp(const LC3_FLOAT x[], const LC3_FLOAT y[], LC3_INT32 n);
      22             : static LC3_FLOAT TDC_get_gainc(const LC3_FLOAT x[], const LC3_FLOAT y[], const LC3_FLOAT *gain_p, const LC3_INT32 n, const LC3_INT32 frame_dms);
      23             : static void TDC_LPC_synthesis(const LC3_FLOAT a[], LC3_FLOAT x[], LC3_FLOAT y[], LC3_INT32 l, const LC3_FLOAT mem[], LC3_INT32 lpcorder, LC3_FLOAT *buf);
      24             : static void TDC_LPC_residu(const LC3_FLOAT *a, LC3_FLOAT *x, LC3_FLOAT *y, LC3_INT32 l, LC3_INT32 lpcorder);
      25             : static void TDC_highPassFiltering(const LC3_INT32 L_buffer, LC3_FLOAT exc2[], const LC3_FLOAT hp_filt[], const LC3_INT32 l_fir_fer);
      26             : static void TDC_f_preemph(LC3_FLOAT *signal, const LC3_FLOAT *mu, LC3_INT32 L, LC3_FLOAT *mem);
      27             : static void TDC_deemph(LC3_FLOAT *signal, const LC3_FLOAT *mu, LC3_INT32 L, const LC3_FLOAT *mem);
      28             : const LC3_FLOAT TDC_high_16[TDC_L_FIR_HP]   = { 0.f,     -0.0205f, -0.0651f, -0.1256f, -0.1792f,  0.8028f, -0.1792f, -0.1256f, -0.0651f, -0.0205f,  0.f    };
      29             : const LC3_FLOAT TDC_high_32[TDC_L_FIR_HP]   = {-0.0517f, -0.0587f, -0.0820f, -0.1024f, -0.1164f,  0.8786f, -0.1164f, -0.1024f, -0.0820f, -0.0587f, -0.0517f};
      30             : const LC3_FLOAT TDC_high_16_harm[TDC_L_FIR_HP]  = { 0.0053f,  0.0000f, -0.0440f,  0.0000f,  0.2637f,  0.5500f,  0.2637f,  0.0000f, -0.0440f,  0.0000f,  0.0053f};
      31             : const LC3_FLOAT TDC_high_32_harm[TDC_L_FIR_HP]  = {-0.0053f, -0.0037f, -0.0140f,  0.0180f,  0.2668f,  0.4991f,  0.2668f,  0.0180f, -0.0140f, -0.0037f, -0.0053f};
      32             : static void TDC_levinson(LC3_FLOAT *acf, LC3_INT32 len, LC3_FLOAT *out);
      33             : static void TDC_copyFLOAT(const LC3_FLOAT * X, LC3_FLOAT * Z, LC3_INT32 n);
      34             : static LC3_FLOAT TDC_dotFLOAT(const LC3_FLOAT * X, const LC3_FLOAT * Y, LC3_INT32 n);
      35             : static LC3_FLOAT type_2_alpha_long(LC3_INT32 nbLostFramesInRow, LC3_INT32 frame_dms);
      36             : const LC3_INT32 beforeNextIncArray[4][4] = {{0,0,0,1},
      37             :                                           {0,1,0,1},
      38             :                                           {0,1,1,1},
      39             :                                           {1,1,1,1}};
      40             : const LC3_INT32 nextIncArray[4][4] = {{1,0,0,0},
      41             :                                     {1,0,1,0},
      42             :                                     {1,0,1,1},
      43             :                                     {1,1,1,1}};
      44             : 
      45           0 : void processTdcApply_fl(const LC3_INT32    pitch_int,
      46             :                         const LC3_FLOAT  *preemphFac,
      47             :                         const LC3_FLOAT* A,
      48             :                         const LC3_INT32    lpc_order,
      49             :                         const LC3_FLOAT* pcmbufHist,
      50             :                         const LC3_INT32    max_len_pcm_plc,
      51             :                         const LC3_INT32    N,
      52             :                         const LC3_INT32    frame_dms,
      53             :                         const LC3_INT32    SampRate,
      54             :                         const LC3_INT32    nbLostFramesInRow,
      55             :                         const LC3_INT32    overlap,
      56             :                         const LC3_FLOAT  *stabFac,
      57             :                         LC3_FLOAT        harmonicBuf[MAX_PITCH],
      58             :                         LC3_FLOAT        synthHist[M],
      59             :                         LC3_INT32*         fract,
      60             :                         LC3_INT16*       seed,
      61             :                         LC3_FLOAT*       gain_c,
      62             :                         LC3_FLOAT*       alpha,
      63             :                         LC3_FLOAT*       synth
      64             :                         , LC3_UINT8       plc_fadeout_type
      65             :                         , LC3_FLOAT*      alpha_type_2_table
      66             :                         )
      67             : {    
      68             :           LC3_FLOAT step, step_n;
      69             :           LC3_INT32   i, len, Tc, nbLostCmpt_loc, nextInc, beforeNextInc;
      70             :           LC3_FLOAT gain_h, tmp, gain_p;
      71             :           LC3_FLOAT *exc2, *exc_buf, *exc, *x_pre, *buf, *pt_exc, *pt1_exc, *synthMemPtr;
      72             :           LC3_FLOAT *harmonicBufPtr;
      73             :           LC3_FLOAT synth_mem[M];
      74             :           const LC3_FLOAT *hp_filt, *high_harm;
      75             :           LC3_FLOAT gainInov;
      76             :           LC3_FLOAT hpBlendFac;
      77             :           char *scratchSpace1st, *scratchSpaceTmp;
      78             :           char scratchSpace[(MAX_LEN_PCM_PLC  + MDCT_MEM_LEN_MAX + MAX_LEN_PCM_PLC + 1 + M) * sizeof(LC3_FLOAT)];
      79             :           LC3_FLOAT alphaPrev;
      80             :           LC3_FLOAT throttle;
      81             :           LC3_INT32   frame_dms_idx, nbLostFramesInRow_mod;
      82           0 :           LC3_INT32 plc_fadeout_len = 0;
      83             :         
      84           0 :   memset(synth_mem, 0, M * sizeof(LC3_FLOAT));
      85           0 :   memset(scratchSpace, 0, (MAX_LEN_PCM_PLC  + MDCT_MEM_LEN_MAX + MAX_LEN_PCM_PLC + 1 + M) * sizeof(LC3_FLOAT));
      86             : 
      87             :   /* len of synthesized signal */
      88           0 :   len = N + overlap;
      89             : 
      90           0 :   nbLostCmpt_loc        = floor(frame_dms/100.0 * (nbLostFramesInRow - 1) + 1);
      91           0 :   frame_dms_idx         = frame_dms / 25 - 1; /* 0,1,2,3 */
      92           0 :   nbLostFramesInRow_mod = (nbLostFramesInRow - 1) % 4;
      93             : 
      94           0 :   beforeNextInc         = beforeNextIncArray[frame_dms_idx][nbLostFramesInRow_mod];
      95           0 :   nextInc               = nextIncArray      [frame_dms_idx][nbLostFramesInRow_mod]; 
      96             : 
      97           0 :   if (plc_fadeout_type >= 1){
      98           0 :     plc_fadeout_len = PLC_FADEOUT_TYPE_1_IN_MS;
      99             :   }
     100             :   else{
     101           0 :     plc_fadeout_len = PLC_FADEOUT_IN_MS;
     102             :   }
     103             : 
     104           0 :   if (nbLostCmpt_loc > plc_fadeout_len/10)
     105             :   {
     106           0 :       gain_p = 0;
     107           0 :       *gain_c = 0;
     108           0 :       *alpha = 0;
     109           0 :       memset(synth, 0, len * sizeof(LC3_FLOAT));
     110           0 :       return;
     111             :   }
     112             : 
     113           0 :   Tc = pitch_int;
     114           0 :   if (*fract > 0) {
     115           0 :     Tc++;
     116             :   }
     117             : 
     118             :   /*----------------------------------------------------------------
     119             :    * Buffer Initialization for timeDomainConcealment_Apply
     120             :    *
     121             :    *            1st
     122             :    * |--exc_buf--|--x_pre--|
     123             :    * |           |--exc2--|
     124             :    * |           |--buf (LPC Syn)--|
     125             :    *
     126             :    *---------------------------------------------------------------*/
     127             :     
     128           0 :   scratchSpace1st = scratchSpace;
     129           0 :   exc_buf = (LC3_FLOAT*)scratchSpace1st; scratchSpace1st += (LC3_INT32)sizeof(LC3_FLOAT) * (Tc + N/2 + len);
     130           0 :   exc = exc_buf + (Tc + N/2);
     131             : 
     132           0 :   scratchSpaceTmp = scratchSpace1st;
     133           0 :   x_pre = (LC3_FLOAT*)scratchSpaceTmp; scratchSpaceTmp += (LC3_INT32)sizeof(LC3_FLOAT) * (lpc_order + Tc + N/2 + 1);
     134             : 
     135             :   /*---------------------------------------------------------------*
     136             :    * LPC Residual                                                  *
     137             :    *---------------------------------------------------------------*/
     138           0 :   if (nbLostFramesInRow == 1)
     139             :   {
     140             :     /* copy buffer to pre-emphasis buffer */
     141           0 :     TDC_copyFLOAT(&(pcmbufHist[max_len_pcm_plc-(lpc_order+Tc+N/2+1)]), &(x_pre[0]), lpc_order+Tc+N/2+1);
     142             : 
     143             :     /* apply pre-emphasis to the signal */
     144           0 :     TDC_f_preemph(&(x_pre[1]), preemphFac, lpc_order+Tc+N/2, &x_pre[0]);
     145             : 
     146             :     /* copy memory for LPC synth */
     147           0 :     TDC_copyFLOAT(&(x_pre[Tc+N/2+1]), synth_mem, lpc_order);
     148             : 
     149             :     /* LPC Residual */
     150           0 :     TDC_LPC_residu(A, &(x_pre[lpc_order+1]), &(exc[-(Tc+N/2)]), Tc+N/2, lpc_order);
     151             :   }
     152             : 
     153             :   /*---------------------------------------------------------------*
     154             :    * Calculate gains                                               *
     155             :    *---------------------------------------------------------------*/
     156           0 :   if (nbLostFramesInRow == 1)
     157             :   {
     158           0 :     if (pitch_int == Tc)
     159             :     {
     160           0 :       gain_p = TDC_get_gainp( &(x_pre[lpc_order+Tc+1]), &(x_pre[lpc_order+1]), N/2 );
     161             :     }
     162             :     else
     163             :     {
     164           0 :       tmp    = TDC_get_gainp( &(x_pre[lpc_order+Tc+1]), &(x_pre[lpc_order+2]), N/2 );
     165           0 :       gain_p = TDC_get_gainp( &(x_pre[lpc_order+Tc+1]), &(x_pre[lpc_order+1]), N/2 );
     166             : 
     167           0 :       if (tmp > gain_p) {
     168           0 :         Tc = pitch_int;
     169           0 :         gain_p = tmp;
     170           0 :         *fract = 0;
     171             :       }
     172             :     }
     173             : 
     174           0 :     if(gain_p < 0.0f)
     175             :     {
     176           0 :       gain_p = 0.0f;
     177             :     }
     178             : 
     179           0 :     if(gain_p > 1.0f)
     180             :     {
     181           0 :       gain_p = 1.0f;
     182             :     }
     183             : 
     184           0 :     *gain_c = 0.0f;
     185             : 
     186           0 :     if (pitch_int == Tc)
     187             :     {
     188           0 :       *gain_c = TDC_get_gainc( &(exc[-1]), &(exc[-1-Tc]), &gain_p, N/2, frame_dms );
     189             :     }
     190             :     else
     191             :     {
     192           0 :       tmp     = TDC_get_gainc( &(exc[-1]), &(exc[-1-pitch_int]), &gain_p, N/2, frame_dms );
     193           0 :       *gain_c = TDC_get_gainc( &(exc[-1]), &(exc[-1-Tc])       , &gain_p, N/2, frame_dms );
     194           0 :       *gain_c = MIN(*gain_c, tmp);
     195             :     }
     196             :   }
     197             :   else
     198             :   {
     199           0 :       gain_p = *alpha;
     200             :   }
     201             : 
     202             :   /*---------------------------------------------------------------*
     203             :    * Damping factor                                                *
     204             :    *---------------------------------------------------------------*/
     205             : 
     206           0 :   alphaPrev = 1;
     207           0 :   if (nbLostFramesInRow > 1)
     208             :   {
     209           0 :       alphaPrev = *alpha;
     210             :   }
     211             : 
     212           0 :   if (plc_fadeout_type == 2){
     213           0 :     *alpha = alpha_type_2_table[nbLostFramesInRow];
     214             :   }
     215             :   else{
     216             : 
     217           0 :   if (nextInc != 0)
     218             :   {
     219           0 :     switch (nbLostCmpt_loc)
     220             :     {
     221           0 :     case 1:
     222           0 :       *alpha = (LC3_FLOAT)sqrt(gain_p);
     223           0 :       if ( *alpha > 0.98f )
     224             :       {
     225           0 :         *alpha = 0.98f;
     226             :       }
     227           0 :       else if ( *alpha < 0.925f )
     228             :       {
     229           0 :         *alpha = 0.925f;
     230             :       }
     231           0 :       break;
     232           0 :     case 2:
     233           0 :       *alpha = (0.63f + 0.35f * (*stabFac)) * gain_p;
     234           0 :       if ( *alpha < 0.919f )
     235             :       {
     236           0 :         *alpha = 0.919f;
     237             :       }
     238           0 :       break;
     239           0 :     default:
     240           0 :       *alpha = (0.652f + 0.328f * (*stabFac)) * gain_p;
     241             :     }
     242           0 :   }
     243             :   
     244           0 :   if (nbLostCmpt_loc > 3)
     245             :   {
     246           0 :       switch (frame_dms)
     247             :       {
     248           0 :       case  25: *alpha *= PLC34_ATTEN_FAC_025; break;
     249           0 :       case  50: *alpha *= PLC34_ATTEN_FAC_025; break;
     250           0 :       case  75: *alpha *= PLC34_ATTEN_FAC_075; break;
     251           0 :       case 100: *alpha *= PLC34_ATTEN_FAC_100; break;
     252             :       }
     253           0 :   }
     254             :   
     255           0 :   if (nbLostCmpt_loc > 5)
     256             :   {
     257           0 :       gain_p = *alpha;
     258             :   }
     259             :   }
     260             :   /*---------------------------------------------------------------*
     261             :    * Construct the harmonic part                                   *
     262             :    *  Last pitch cycle of the previous frame is repeatedly copied. *
     263             :    *---------------------------------------------------------------*/
     264             : 
     265           0 :   pt_exc = harmonicBuf;
     266           0 :   pt1_exc = exc - Tc;
     267             : 
     268           0 :   if( nbLostFramesInRow == 1 ) 
     269             :   {
     270           0 :     if (*stabFac >= 1)
     271             :     {
     272           0 :         TDC_copyFLOAT(pt1_exc, pt_exc, Tc);
     273             :     }
     274             :     else 
     275             :     {
     276             :       /* These values are necessary for the last five filtered samples */
     277           0 :       TDC_copyFLOAT(&exc[-Tc], exc, (TDC_L_FIR_HP-1)/2);
     278             : 
     279           0 :       high_harm = TDC_high_32_harm;
     280           0 :       if (SampRate <= 16000)
     281             :       {
     282           0 :           high_harm = TDC_high_16_harm;
     283             :       }
     284             :       
     285           0 :       for( i = 0; i < Tc; i++ )
     286             :       {
     287           0 :           pt_exc[i] = TDC_dotFLOAT(&pt1_exc[i-(TDC_L_FIR_HP-1)/2], high_harm, TDC_L_FIR_HP);
     288             :       }
     289             :     }
     290             :   }
     291             : 
     292             :   /*---------------------------------------------------------------*
     293             :    * Construct the random part of excitation                       *
     294             :    *---------------------------------------------------------------*/
     295           0 :   scratchSpaceTmp = scratchSpace1st;
     296           0 :   exc2 = (LC3_FLOAT*)scratchSpaceTmp; scratchSpaceTmp += (LC3_INT32)sizeof(LC3_FLOAT) * (len + TDC_L_FIR_HP - 1);
     297             : 
     298           0 :   for (i = 0; i < len + TDC_L_FIR_HP - 1; i++) {
     299           0 :     exc2[i] = (LC3_FLOAT)TDC_random_short(seed);
     300             :   }
     301             : 
     302             :   /* high pass noise */
     303           0 :   if (SampRate <= 16000 )
     304             :   {
     305           0 :     hp_filt = TDC_high_16;
     306             :   } else {
     307           0 :     hp_filt = TDC_high_32;
     308             :   }
     309             : 
     310           0 :   if ( nbLostFramesInRow == 1 )
     311             :   {
     312           0 :     TDC_highPassFiltering(len, exc2, hp_filt, TDC_L_FIR_HP);
     313             :   }
     314             :   else
     315             :   {
     316             :     /* moves from 0 to 1, speed is defined by PLC3_HPBLENDTHROTTLE */
     317           0 :     throttle = (LC3_FLOAT)nbLostCmpt_loc / (nbLostCmpt_loc + PLC3_HPBLENDTHROTTLE);
     318           0 :     hpBlendFac = (1 - *alpha) * throttle;
     319             : 
     320           0 :     for (i = 0; i < len; i++)
     321             :     {
     322           0 :       exc2[i] =  hpBlendFac * exc2[i+TDC_L_FIR_HP/2] + (1 - hpBlendFac) * TDC_dotFLOAT(&exc2[i], hp_filt, TDC_L_FIR_HP );
     323             :     }
     324             :   }
     325             : 
     326             :   /* normalize energy */
     327           0 :   gainInov = 1.0f / (LC3_FLOAT)sqrt(TDC_dotFLOAT( exc2, exc2, N ) / (LC3_FLOAT)N + 0.01f );
     328           0 :   gainInov *= (1.1f - 0.75* gain_p);
     329             : 
     330             :   /* gains */
     331           0 :   gain_h = alphaPrev;
     332           0 :   tmp = *gain_c * *alpha / alphaPrev;
     333             : 
     334             :   /* update steps */
     335           0 :   step = (1.0f/(LC3_FLOAT)N) * (gain_h - *alpha);
     336           0 :   step_n = (1.0f/(LC3_FLOAT)N) * (*gain_c - tmp);
     337             : 
     338             :   /*---------------------------------------------------------------*
     339             :    * Construct the total excitation                                *
     340             :    *---------------------------------------------------------------*/
     341           0 :   harmonicBufPtr = harmonicBuf + ((nbLostFramesInRow - 1) * N) % Tc;
     342             : 
     343           0 :   for ( i = 0; i < len; i++ ) {
     344             :     /* harmonic */
     345           0 :     if (harmonicBufPtr - harmonicBuf >= Tc) {
     346           0 :         harmonicBufPtr = harmonicBuf;
     347             :     }
     348           0 :     exc[i] = *harmonicBufPtr++;
     349           0 :     exc[i] *= gain_h;
     350             : 
     351             :     /* random */
     352           0 :     exc2[i] *= *gain_c * gainInov;
     353             : 
     354             :     /* total */
     355           0 :     exc[i] = exc[i] + exc2[i];
     356             : 
     357             :     /* update */
     358           0 :     gain_h -= step;
     359           0 :     gain_h = MAX(gain_h, 0);
     360           0 :     *gain_c -= step_n;
     361           0 :     *gain_c = MAX(*gain_c, 0);
     362             :   }
     363             : 
     364           0 :   *gain_c = tmp;
     365             : 
     366             :   /*----------------------------------------------------------*
     367             :    * Compute the synthesis speech                             *
     368             :    *----------------------------------------------------------*/
     369           0 :   buf = (LC3_FLOAT*)scratchSpace1st; scratchSpace1st += (LC3_INT32)sizeof(LC3_FLOAT) * (len + lpc_order);
     370           0 :   synthMemPtr = synth_mem;
     371           0 :   if (nbLostFramesInRow != 1)
     372             :   {
     373           0 :       synthMemPtr = synthHist;
     374             :   }
     375             :   
     376           0 :   TDC_LPC_synthesis(A,
     377             :                     &exc[0],
     378             :                     synth,
     379             :                     len,
     380             :                     synthMemPtr,
     381             :                     lpc_order,
     382             :                     buf);
     383             : 
     384           0 :   TDC_copyFLOAT(&synth[N-lpc_order], synthHist, lpc_order);
     385             : 
     386             :   /*----------------------------------------------------------*
     387             :    * Deemphasis                                               *
     388             :    *----------------------------------------------------------*/
     389           0 :   TDC_deemph( synth, preemphFac, len, &pcmbufHist[max_len_pcm_plc-1] );
     390             : 
     391             :   /*----------------------------------------------------------*
     392             :    * Fade to zero                                             *
     393             :    *----------------------------------------------------------*/
     394           0 :   if (beforeNextInc != 0)
     395             :   {
     396           0 :     if (nbLostCmpt_loc == plc_fadeout_len/10)
     397             :     {
     398           0 :       gain_h = 1;
     399           0 :       step = 1.0f/(LC3_FLOAT)N;
     400           0 :       for ( i = 0; i < N; i++ ) {
     401           0 :         synth[i] *= gain_h;
     402           0 :         gain_h -= step;
     403             :       }
     404           0 :       memset(&synth[N], 0, overlap * sizeof(LC3_FLOAT));
     405             :     }
     406             :   }
     407             : }
     408             : 
     409             : /* Take only real part */
     410           0 : void processTdcInverseOdft_fl(LC3_FLOAT *in, LC3_INT32 n_bands, LC3_FLOAT *out, LC3_INT32 lpc_order)
     411             : {
     412             :         LC3_INT32 i, j, k;
     413             :         LC3_FLOAT buf[2*MAX_BANDS_NUMBER_PLC];
     414             :         Complex sum;
     415             :         Complex res;
     416             : 
     417             :     /* Buffer for ifft */
     418           0 :     j = 0;
     419           0 :     for (i = 0; i < n_bands - 1; i += 2)
     420             :     {
     421           0 :         buf[j] = in[i];
     422           0 :         j++;
     423             :     }
     424             : 
     425           0 :     for (i = n_bands - 1; i > 0; i -= 2)
     426             :     {
     427           0 :         buf[j] = in[i];
     428           0 :         j++;
     429             :     }
     430             : 
     431           0 :     for (i = 0; i < n_bands; i++)
     432             :     {
     433           0 :         buf[j] = in[i];
     434           0 :         j++;
     435             :     }
     436             : 
     437             :     /* ifft */
     438           0 :     for (j = 0; j < n_bands; j++)
     439             :     {
     440           0 :         sum.r = 0, sum.i = 0;
     441           0 :         res.r = 0, res.i = 0;
     442           0 :         for (k = 0; k < n_bands; k++)
     443             :         {
     444           0 :             res = cexpi((2 * M_PI_LC3PLUS  * (LC3_FLOAT) (j * k)) / (LC3_FLOAT) n_bands);
     445           0 :             res.r = res.r * buf[k];
     446           0 :             res.i = res.i * buf[k];
     447           0 :             sum = cadd(sum, res);
     448             :         }
     449             : 
     450           0 :         res = cexpi((LC3_FLOAT) j * M_PI_LC3PLUS / (2.0 * (LC3_FLOAT) n_bands));
     451           0 :         out[j] = (sum.r * res.r - sum.i * res.i);
     452             :     }
     453             : 
     454           0 :     out[0] = out[0] * 1.0001;
     455           0 :     if (out[0] == 0)
     456             :     {
     457           0 :         out[0] = 1;
     458           0 :         zero_float(&out[1], lpc_order);
     459             :     }
     460           0 : }
     461             : 
     462           0 : void processTdcPreemphasis_fl(LC3_FLOAT *in, LC3_FLOAT *pre_emph_factor, LC3_INT32 n_bands)
     463             : {
     464             :         LC3_INT32 i;
     465             : 
     466           0 :     for (i = 0; i < n_bands; i++)
     467             :     {
     468           0 :         in[i] = in[i] * (1.0 - 2.0 * (*pre_emph_factor) * LC3_COS(2.0 * M_PI_LC3PLUS * (0.5 + (LC3_FLOAT) i) / (2.0 * (LC3_FLOAT) n_bands)) + (*pre_emph_factor) * (*pre_emph_factor));
     469             :     }
     470           0 : }
     471             : 
     472           0 : void processTdcLpcEstimation_fl(LC3_FLOAT *r, LC3_INT32 fs_idx, LC3_INT32 len, LC3_FLOAT *A, LC3_INT32 frame_dms)
     473             : {
     474             :         LC3_INT32 i;
     475             :         const LC3_FLOAT *lpc_array;
     476             :     
     477           0 :     lpc_array = plc_tdc_lpc_all[fs_idx];
     478             :     
     479           0 :     if (fs_idx == 0 && frame_dms == 25)
     480             :     {
     481           0 :         lpc_array = plc_tdc_lpc_8_25ms;
     482             :     }
     483             :     
     484             :     /* r[0] = r[0] * 1 */
     485           0 :     for (i = 1; i < len; i++)
     486             :     {
     487           0 :         r[i] = r[i] * lpc_array[i];
     488             :     }
     489             : 
     490           0 :     TDC_levinson(r, len - 1, A);
     491           0 : }
     492             : 
     493             : /** random
     494             :  *
     495             :  * Parameters:
     496             :  *    seed        I/O: seed for random number
     497             :  *
     498             :  * Function:
     499             :  *    Signed 16 bits random generator.
     500             :  *
     501             :  * Returns:
     502             :  *    random number
     503             :  */
     504           0 : static LC3_INT16 TDC_random_short(LC3_INT16 *seed)
     505             : {
     506           0 :    *seed = (LC3_INT16) (*seed * 12821L + 16831L);
     507           0 :    return(*seed);
     508             : }
     509             : 
     510           0 : static LC3_FLOAT TDC_get_gainp( /* output: gain of pitch                        */
     511             :   const LC3_FLOAT x[],      /* input : input signal                         */
     512             :   const LC3_FLOAT y[],      /* input : shifted input signal                 */
     513             :   LC3_INT32 n                 /* input : vector length                        */
     514             : )
     515             : {
     516             :         LC3_FLOAT corr, ener;
     517             :         LC3_INT16 i;
     518             :     
     519           0 :     corr = 0; ener = 1e-6f;
     520             : 
     521           0 :     for (i = 0; i < n; i++)
     522             :     {
     523           0 :         corr += x[i]*y[i];
     524           0 :         ener += y[i]*y[i];
     525             :     }
     526             : 
     527           0 :     return(corr/ener);
     528             : }
     529             : 
     530           0 : static LC3_FLOAT TDC_get_gainc( /* output: gain of code                         */
     531             :   const LC3_FLOAT x[],      /* input : input signal                         */
     532             :   const LC3_FLOAT y[],      /* input : shifted input signal                 */
     533             :   const LC3_FLOAT *gain_p,   /* input : gain of pitch                        */
     534             :   const LC3_INT32   n,        /* input : vector length                        */
     535             :   const LC3_INT32   frame_dms /* input : frame length in dms                  */
     536             : )
     537             : {
     538             :         LC3_FLOAT gain_c;
     539             :         LC3_FLOAT gain_c_max;
     540             :         LC3_INT16 i;
     541             :     
     542           0 :     gain_c = 0; gain_c_max = 0;
     543             : 
     544           0 :     for (i = 0; i < n; i++)
     545             :     {
     546           0 :       gain_c += ( x[-i] - *gain_p * y[-i] ) * ( x[-i] - *gain_p * y[-i] );
     547             :     }
     548             : 
     549           0 :     if (frame_dms < 100)
     550             :     {
     551           0 :         for (i = 0; i < n; i++)
     552             :         {
     553           0 :           gain_c_max += (x[-i] * x[-i]);
     554             :         }
     555           0 :         gain_c = MIN(gain_c, gain_c_max);
     556             :     }
     557             : 
     558           0 :     gain_c = (LC3_FLOAT)sqrt(gain_c / n );
     559             : 
     560           0 :     return gain_c;
     561             : }
     562             : 
     563           0 : static void TDC_highPassFiltering(const LC3_INT32   L_buffer,      /* i:   buffer length                                      */
     564             :                        LC3_FLOAT       exc2[],        /* i/o: unvoiced excitation before the high pass filtering */
     565             :                        const LC3_FLOAT hp_filt[],     /* i:   high pass filter coefficients                      */
     566             :                        const LC3_INT32   l_fir_fer)     /* i:   high pass filter length                            */
     567             : {
     568             :        LC3_INT32   i;
     569             :     
     570           0 :   for( i=0 ; i< L_buffer; i++ ) {
     571           0 :     exc2[i] = TDC_dotFLOAT(&exc2[i], hp_filt, l_fir_fer);
     572             :   }
     573           0 : }
     574             : 
     575           0 : static void TDC_LPC_synthesis(
     576             :                        const LC3_FLOAT a[],
     577             :                        LC3_FLOAT       x[],
     578             :                        LC3_FLOAT       y[],
     579             :                        LC3_INT32         l,
     580             :                        const LC3_FLOAT mem[],
     581             :                        LC3_INT32         lpcorder,
     582             :                        LC3_FLOAT      *buf
     583             :                        )
     584             : {
     585             :        LC3_FLOAT s, *yy;
     586             :        LC3_INT32   i, j;
     587             : 
     588             :    /* copy initial filter states into synthesis buffer */
     589           0 :    for (i=0; i < lpcorder; i++)
     590             :    {
     591           0 :       buf[i] = mem[i];
     592             :    }
     593           0 :    yy = &buf[i];
     594             : 
     595           0 :    for (i = 0; i < l; i++)
     596             :    {
     597           0 :       s =  x[i];
     598           0 :       for (j = 1; j <= lpcorder; j++)
     599             :       {
     600           0 :           s -= a[j] * yy[i- j];
     601             :       }
     602           0 :       y[i] = s;
     603           0 :       yy[i] = y[i];
     604             :    }
     605             : 
     606           0 :    return;
     607             : }
     608             : 
     609             : 
     610             : /** TDC_LPC_residu
     611             :  *
     612             :  * Parameters:
     613             :  *    a           I: LP filter coefficients (Q12)
     614             :  *    x           I: input signal (usually speech)
     615             :  *    y           O: output signal (usually residual)
     616             :  *    l           I: size of filtering
     617             :  *    lpcorder    I: Order of LP filter
     618             :  *
     619             :  * Function:
     620             :  *    Compute the LP residual by filtering the input speech through A(z).
     621             :  *
     622             :  * Returns:
     623             :  *    void
     624             :  */
     625           0 : static void TDC_LPC_residu(const LC3_FLOAT *a, LC3_FLOAT *x, LC3_FLOAT *y, LC3_INT32 l, LC3_INT32 lpcorder)
     626             : {
     627             :        LC3_FLOAT s;
     628             :        LC3_INT32   i, j;
     629             : 
     630           0 :    for (i = 0; i < l; i++)
     631             :    {
     632           0 :       s = x[i];
     633           0 :       for (j = 1; j <= lpcorder; j++)
     634             :       {
     635           0 :          s += a[j] * x[i - j];
     636             :       }
     637           0 :       y[i] = s;
     638             :    }
     639             : 
     640           0 :    return;
     641             : }
     642             : 
     643             : 
     644             : /** TDC_f_preemph
     645             :  *
     646             :  * Parameters:
     647             :  *    signal       I/O: signal
     648             :  *    mu             I: preemphasis factor
     649             :  *    L              I: vector size
     650             :  *    mem            I: memory (x[-1])
     651             :  *
     652             :  * Function:
     653             :  *    Filtering through 1 - mu z^-1
     654             :  *
     655             :  *
     656             :  * Returns:
     657             :  *    void
     658             :  */
     659             : 
     660           0 : static void TDC_f_preemph(LC3_FLOAT *signal, const LC3_FLOAT *mu, LC3_INT32 L, LC3_FLOAT *mem)
     661             : {
     662             :       LC3_INT32 i;
     663             : 
     664           0 :    for (i = L - 1; i > 0; i--)
     665             :    {
     666           0 :       signal[i] = signal[i] - *mu * signal[i - 1];
     667             :    }
     668             : 
     669           0 :    signal[0] -= *mu * (*mem);
     670             : 
     671           0 :    return;
     672             : }
     673             : 
     674             : /*
     675             :  * TDC_deemph
     676             :  *
     677             :  * Parameters:
     678             :  *    signal       I/O: signal
     679             :  *    mu             I: deemphasis factor
     680             :  *    L              I: vector size
     681             :  *    mem            I: memory (signal[-1])
     682             :  *
     683             :  * Function:
     684             :  *    Filtering through 1/(1-mu z^-1)
     685             :  *    Signal is divided by 2.
     686             :  *
     687             :  * Returns:
     688             :  *    void
     689             :  */
     690           0 : static void TDC_deemph(LC3_FLOAT *signal, const LC3_FLOAT *mu, LC3_INT32 L, const LC3_FLOAT *mem)
     691             : {
     692             :       LC3_INT32 i;
     693             : 
     694           0 :    signal[0] = signal[0] + *mu * (*mem);
     695             : 
     696           0 :    for (i = 1; i < L; i++)
     697             :    {
     698           0 :       signal[i] = signal[i] + *mu * signal[i - 1];
     699             :    }
     700             : 
     701           0 :    return;
     702             : }
     703             : 
     704           0 : static void TDC_copyFLOAT(const LC3_FLOAT * X, LC3_FLOAT * Z, LC3_INT32 n)
     705             : {
     706             :   /* no values to copy */
     707           0 :   if ( (n < 1) || (X == Z) ){
     708           0 :     return;
     709             :   }
     710             :   /* If overlapping */
     711           0 :   if ( ( (Z > X) && (Z < X+n) ) || ( (Z < X) && (X < Z+n) ) ) {
     712           0 :     memmove(Z, X, sizeof(LC3_FLOAT)*n);
     713             :   }
     714             :   else{
     715           0 :     memcpy(Z, X, sizeof(LC3_FLOAT)*n);
     716             :   }
     717             : }
     718             : 
     719           0 : static LC3_FLOAT TDC_dotFLOAT(const LC3_FLOAT * X, const LC3_FLOAT * Y, LC3_INT32 n)
     720             : {
     721             :       LC3_FLOAT acc;
     722             :       LC3_INT32 i;
     723             : 
     724           0 :   acc = 0;
     725           0 :   if (n) {
     726           0 :     acc = X[0]*Y[0];
     727             :   }
     728             : 
     729           0 :   for (i=1; i<n; i++) acc += X[i]*Y[i];
     730             :     
     731           0 :   return acc;
     732             : }
     733             : 
     734           0 : static void TDC_levinson(LC3_FLOAT *acf, LC3_INT32 len, LC3_FLOAT *out)
     735             : { 
     736             :         LC3_FLOAT g, v, sum, buf[M], buf2[M];
     737             :         LC3_INT32 i, j, k, t;
     738             : 
     739           0 :     g = acf[1] / acf[0];
     740             : 
     741           0 :     out[0] = g;
     742           0 :     v = (1.0 - g * g) * acf[0];
     743             : 
     744           0 :     for (t = 1; t < len; t++)
     745             :     {
     746           0 :         sum = 0; j = 0;
     747           0 :         for (i = 1; i <= t; i++)
     748             :         {
     749           0 :             sum += out[j] * acf[i];
     750           0 :             j++;
     751             :         }
     752             : 
     753           0 :         g = (acf[t + 1] - sum) / v;
     754             : 
     755           0 :         move_float(buf, out, len);
     756           0 :         move_float(buf2, out, len);
     757           0 :         out[0] = g;
     758             : 
     759           0 :         j = 1, k = 0;
     760           0 :         for (i = t - 1; i >= 0; i--)
     761             :         {
     762           0 :             out[j] = buf[k] - g * buf2[i];
     763           0 :             j++; k++;
     764             :         }
     765             : 
     766           0 :         v = v * (1.0 - g * g);
     767             :     }
     768             : 
     769           0 :     move_float(buf, out, len);
     770           0 :     out[0] = 1;
     771             : 
     772           0 :     j = 1;
     773           0 :     for (i = len - 1; i >= 0; i--)
     774             :     {
     775           0 :         out[j] = -buf[i];
     776           0 :         j++;
     777             :     }
     778           0 : }
     779             : 
     780           0 : static LC3_FLOAT type_2_alpha_long(LC3_INT32 nbLostFramesInRow, LC3_INT32 frame_dms)
     781             : {   
     782           0 :     if (nbLostFramesInRow <= 3*100.0/frame_dms){
     783           0 :        return LC3_POW(0.95,(nbLostFramesInRow + (100.0/frame_dms) - 1) * frame_dms/100.0);
     784             :     }
     785             :     else {
     786           0 :       LC3_INT32 n_shift = (nbLostFramesInRow - 3*100.0/frame_dms) * 50/frame_dms;
     787           0 :       return LC3_POW(0.7,(n_shift + 100.0/frame_dms - 1) * frame_dms/100.0);
     788             :     }
     789             : }
     790             : 
     791           0 : LC3_FLOAT type_2_fadeout(LC3_INT32 nbLostFramesInRow, LC3_INT32 frame_dms)
     792             : {   
     793           0 :     LC3_FLOAT selector = PLC_FADEOUT_TYPE_2_SELECTOR * 2 * 100/frame_dms;
     794           0 :     if (selector >= nbLostFramesInRow){
     795           0 :       return type_2_alpha_long(nbLostFramesInRow, frame_dms);
     796             :     }
     797             :     else {
     798           0 :       return LC3_POW(0.5,(nbLostFramesInRow + (100.0/frame_dms) - 1) * frame_dms/100.0);
     799             :     } 
     800             : }

Generated by: LCOV version 1.14