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 @ 867217ee32c8e8cd2cf5aae69e60c58e00160b49 Lines: 265 280 94.6 %
Date: 2025-12-13 06:47:12 Functions: 17 17 100.0 %

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

Generated by: LCOV version 1.14