LCOV - code coverage report
Current view: top level - lib_lc3plus - tns_coder.c (source / functions) Hit Total Coverage
Test: Coverage on main -- merged total coverage @ a21f94bc6bac334fe001a5bad2f7b32b79038097 Lines: 140 195 71.8 %
Date: 2025-11-01 08:50:45 Functions: 3 5 60.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             : #include "options.h"
      11             : #include "wmc_auto.h"
      12             : #include "functions.h"
      13             : 
      14             : static void xcorr(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT lag, LC3_INT inLen);
      15             : static void levdown(LC3_FLOAT* anxt, LC3_FLOAT* out_a, LC3_INT* len);
      16             : static void poly2rc(LC3_FLOAT* a, LC3_FLOAT* out, LC3_INT len);
      17             : 
      18     7191303 : void xcorr(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT lag, LC3_INT inLen)
      19             : {
      20             :         LC3_INT32   m;
      21             : 
      22             : 
      23    45114510 :     for (m = 0; m <= lag; m++) {
      24             :         /* Calculate correlation */
      25    37923207 :         out[m] = mac_loop(in, &in[m], (inLen - m));
      26             :     }
      27     7191303 : }
      28             : 
      29     3540974 : void levinsonDurbin(LC3_FLOAT* r, LC3_FLOAT* out_lev, LC3_FLOAT* rc_unq, LC3_FLOAT* error, LC3_INT len)
      30             : {
      31             :     LC3_INT   t, i, j;
      32             :     LC3_FLOAT g, v, sum, buf_tmp[10];
      33             : 
      34     3540974 :     g          = r[1] / r[0];
      35     3540974 :     out_lev[0] = g;
      36             : 
      37     3540974 :     v         = (1.0 - g * g) * r[0];
      38     3540974 :     rc_unq[0] = -g;
      39             : 
      40    14820628 :     for (t = 1; t < len; t++) {
      41             : 
      42    11279654 :         sum = 0;
      43    36137524 :         for (i = 1; i <= t; i++) {
      44    24857870 :             sum += out_lev[i - 1] * r[i];
      45             :         }
      46             : 
      47    11279654 :         g = (r[t + 1] - sum) / v;
      48             : 
      49    11279654 :         j = 1;
      50    36137524 :         for (i = t - 1; i >= 0; i--) {
      51    24857870 :             buf_tmp[j] = out_lev[j - 1] - g * out_lev[i];
      52    24857870 :             j++;
      53             :         }
      54             : 
      55    11279654 :         move_float(&out_lev[1], &buf_tmp[1], len);
      56             : 
      57    11279654 :         out_lev[0] = g;
      58             : 
      59    11279654 :         v         = v * (1 - g * g);
      60    11279654 :         rc_unq[t] = -g;
      61             :     }
      62             : 
      63             :     /* Reorder out_lev */
      64     3540974 :     out_lev[0] = 1;
      65     3540974 :     j          = 1;
      66    18361602 :     for (i = len - 1; i >= 0; i--) {
      67    14820628 :         buf_tmp[j] = -out_lev[i];
      68    14820628 :         j++;
      69             :     }
      70             : 
      71     3540974 :     move_float(&out_lev[1], &buf_tmp[1], (len - 1));
      72             : 
      73     3540974 :     out_lev[len] = rc_unq[len - 1];
      74             : 
      75     3540974 :     *error = v;
      76     3540974 : }
      77             : 
      78           0 : void levdown(LC3_FLOAT* anxt, LC3_FLOAT* out_a, LC3_INT* len)
      79             : {
      80             :     LC3_INT32   i, j;
      81             :     LC3_FLOAT tmp_buf[8], knxt;
      82             :     LC3_FLOAT norm;
      83             : 
      84           0 :         memset(tmp_buf, 0, 8 * sizeof(LC3_FLOAT));
      85             :     /* Initial length = 9 */
      86             : 
      87             :     /* Drop the leading 1 */
      88             : 
      89           0 :     *len = *len - 1; /* Lenght = 8 */
      90             : 
      91             :     /* Last coefficient */
      92           0 :     knxt = anxt[*len]; /* At [7] */
      93             : 
      94           0 :     *len = *len - 1; /* Lenght = 7 */
      95             : 
      96           0 :     j = 0;
      97           0 :     for (i = *len - 1; i >= 0; i--) {
      98           0 :         tmp_buf[j] = knxt * anxt[i + 1];
      99           0 :         j++;
     100             :     }
     101             :     
     102           0 :     norm = 1.0 / (1.0 - (LC3_FABS(knxt)) * (LC3_FABS(knxt)));
     103             : 
     104           0 :     out_a[0] = 1;
     105           0 :     for (i = 0; i < *len; i++) {
     106           0 :         out_a[i + 1] = (anxt[i + 1] - tmp_buf[i]) * norm;
     107             :     }
     108             : 
     109           0 :     *len = *len + 1; /* Length = 8 */
     110           0 : }
     111             : 
     112           0 : void poly2rc(LC3_FLOAT* a, LC3_FLOAT* out, LC3_INT len)
     113             : {
     114             :     LC3_INT   k, i, len_old;
     115             :     LC3_FLOAT buf[9];
     116             : 
     117           0 :     len_old = len;
     118             : 
     119           0 :     zero_float(out, len - 1);
     120             : 
     121             :     /* Length = 9 */
     122             : 
     123             :     /* Normalize */
     124           0 :     for (i = 0; i < len; i++) {
     125           0 :         a[i] = a[i] / a[0];
     126             :     }
     127             : 
     128           0 :     out[len - 1] = a[len - 1];
     129             : 
     130             :     /* Process */
     131           0 :     for (k = len - 2; k >= 0; k--) {
     132           0 :         levdown(a, buf, &len);
     133           0 :         out[k] = buf[len - 1]; /* Store last value */
     134             : 
     135           0 :         move_float(a, buf, len);
     136             :     }
     137             : 
     138             :     /* Shift output array by one to the left to lose leading 1 */
     139           0 :     for (i = 0; i < len_old - 1; i++) {
     140           0 :         out[i] = out[i + 1];
     141             :     }
     142           0 : }
     143             : 
     144             : 
     145     1779817 : void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, LC3_INT fs, LC3_INT N, LC3PLUS_FrameDuration frame_dms, LC3_INT nBits,
     146             :                         LC3_INT* order_out, LC3_INT* rc_idx, LC3_INT* tns_numfilters, LC3_INT* bits_out
     147             :                         , LC3_INT16 near_nyquist_flag
     148             : )
     149             : {
     150             :     LC3_INT i, stopfreq[2], startfreq[2], f, numfilters, maxOrder, bits, sub,
     151             :         subdiv_startfreq, subdiv_stopfreq, j, rc_idx_tmp[MAXLAG], order_tmp, tmp, tns;
     152             :     LC3_FLOAT minPGfac, minPredictionGain, maxPG, xcorr_out[MAXLAG + 1], sum,
     153             :           subdiv_len, nSubdivisions, r[MAXLAG + 1], rc_unq[MAXLAG + 1], error_lev, predGain,
     154     1779817 :           alpha, rc[MAXLAG], st[MAXLAG + 1] = {0}, s, tmpSave, tmp_fl;
     155             :     const LC3_INT* order;
     156             :     LC3_FLOAT inv_sum, x_val;
     157             :     LC3_FLOAT alpha_loc;
     158             :     LC3_INT32 iIndex;
     159             : 
     160             :     /* Init */
     161             : 
     162     1779817 :     if (fs >= 32000 && frame_dms >= LC3PLUS_FRAME_DURATION_5MS) {
     163     1779797 :         numfilters = 2;
     164             :     } else {
     165          20 :         numfilters = 1;
     166             :     }
     167             : 
     168             :     /* 40 * frame_dms / 10 = 4 * frame_dms */
     169     1779817 :     if (N > 40 * ((LC3_FLOAT) (frame_dms*1.25*10) / 10.0)) {
     170     1779809 :         N  = 40 * ((LC3_FLOAT) (frame_dms*1.25*10) / 10.0);
     171     1779809 :         fs = 40000;
     172             :     }
     173             : 
     174     1779817 :     if (numfilters == 1) {
     175          20 :         startfreq[0] = floor(600 * N * 2 / fs) + 1;
     176          20 :         stopfreq[0]  = N;
     177             :     } else {
     178     1779797 :         startfreq[0] = floor(600 * N * 2 / fs) + 1;
     179     1779797 :         startfreq[1] = N / 2 + 1;
     180     1779797 :         stopfreq[0]  = N / 2;
     181     1779797 :         stopfreq[1]  = N;
     182             :     }
     183             :     
     184     1779817 :     switch (frame_dms)
     185             :     {
     186             : #ifdef CR9_C_ADD_1p25MS
     187           0 :         case LC3PLUS_FRAME_DURATION_1p25MS:
     188           0 :             maxOrder      = 4;
     189           0 :             nSubdivisions = 2.0;
     190           0 :             break;
     191             : #endif
     192          16 :         case LC3PLUS_FRAME_DURATION_2p5MS:
     193          16 :             maxOrder      = 4;
     194          16 :             nSubdivisions = 2.0;
     195          16 :             break;
     196     1697637 :         case LC3PLUS_FRAME_DURATION_5MS:
     197     1697637 :             maxOrder      = 4;
     198     1697637 :             nSubdivisions = 2.0;
     199     1697637 :             break;
     200           0 :         case LC3PLUS_FRAME_DURATION_7p5MS:
     201           0 :             maxOrder      = 8;
     202           0 :             nSubdivisions = 3;
     203           0 :             break;
     204       82164 :         case LC3PLUS_FRAME_DURATION_10MS:
     205       82164 :             maxOrder      = 8;
     206       82164 :             nSubdivisions = 3.0;
     207       82164 :             break;
     208           0 :         case LC3PLUS_FRAME_DURATION_UNDEFINED:
     209           0 :             assert(0);
     210             :     }
     211             : 
     212     1779817 :     minPredictionGain = 1.5;
     213             : 
     214     1779817 :     if (nBits >= 4.8 * ((LC3_FLOAT) frame_dms * 1.25 * 10)) {
     215     1779817 :         order = order1_tns;
     216             :     } else {
     217           0 :         order = order2_tns;
     218             :     }
     219             :     
     220             :     /* Processing */
     221     1779817 :     if (bw_cutoff_idx >= 3 && numfilters == 2) {
     222     1761157 :         numfilters   = 2;
     223     1761157 :         startfreq[1] = bw_fcbin / 2 + 1;
     224     1761157 :         stopfreq[0]  = bw_fcbin / 2;
     225     1761157 :         stopfreq[1]  = bw_fcbin;
     226             :     } else {
     227       18660 :         numfilters  = 1;    
     228       18660 :         stopfreq[0] = bw_fcbin;
     229             :     }
     230             : 
     231     1779817 :     bits = 0;
     232             : 
     233     5320791 :     for (f = 0; f < numfilters; f++) {
     234     3540974 :         subdiv_len = ((LC3_FLOAT)stopfreq[f] + 1.0 - (LC3_FLOAT)startfreq[f]) / nSubdivisions;
     235             : 
     236     3540974 :         zero_float(r, MAXLAG+1);
     237             : 
     238    10732277 :         for (sub = 1; sub <= nSubdivisions; sub++) {
     239     7218573 :             subdiv_startfreq = floor(subdiv_len * (sub - 1)) + startfreq[f] - 1;
     240     7218573 :             subdiv_stopfreq  = floor(subdiv_len * sub) + startfreq[f] - 1;
     241             :             
     242     7218573 :             if (fs == 32000 && frame_dms == 75)
     243             :             {
     244           0 :                 if (subdiv_startfreq == 83)
     245             :                 {
     246           0 :                     subdiv_startfreq = 82;
     247             :                 }
     248             :                 
     249           0 :                 if (subdiv_stopfreq == 83)
     250             :                 {
     251           0 :                     subdiv_stopfreq = 82;
     252             :                 }
     253             :                 
     254           0 :                 if (subdiv_startfreq == 160)
     255             :                 {
     256           0 :                     subdiv_startfreq = 159;
     257             :                 }
     258             :                 
     259           0 :                 if (subdiv_stopfreq == 160)
     260             :                 {
     261           0 :                     subdiv_stopfreq = 159;
     262             :                 }
     263             :             }
     264             : 
     265     7218573 :             sum = 0;
     266   363010182 :             for (i = subdiv_startfreq; i < subdiv_stopfreq; i++) {
     267   355791609 :                 sum += x[i] * x[i];
     268             :             }
     269             : 
     270     7218573 :             if (sum < LC3_EPS) {
     271       27270 :                 zero_float(r, MAXLAG+1);
     272       27270 :                 r[0] = 1;
     273       27270 :                 break;
     274             :             }
     275             : 
     276     7191303 :             xcorr(&x[subdiv_startfreq], xcorr_out, maxOrder, subdiv_stopfreq - subdiv_startfreq);
     277             : 
     278     7191303 :             inv_sum = 1.0 / sum;
     279    45114510 :             for (i = 0; i <= maxOrder; i++) {
     280    37923207 :                 r[i] = r[i] + xcorr_out[i] * inv_sum;
     281             :             }
     282             :         }
     283             : 
     284    21902576 :         for (i = 0; i <= maxOrder; i++) {
     285    18361602 :             r[i] = r[i] * lagw_tns[i];
     286             :         }
     287             : 
     288     3540974 :         levinsonDurbin(r, xcorr_out, rc_unq, &error_lev, maxOrder);
     289             : 
     290     3540974 :         predGain = r[0] / error_lev;
     291             : 
     292     3540974 :         if (predGain > minPredictionGain && near_nyquist_flag == 0) {
     293      284451 :             tns = 1;
     294             :         } else {
     295     3256523 :             tns = 0;
     296             :         }
     297             : 
     298     3540974 :         bits++;
     299             : 
     300     3540974 :         if (tns == 1) {
     301      284451 :             minPGfac = 0.85;
     302      284451 :             maxPG    = 2;
     303      284451 :             if (nBits >= 4.8 * frame_dms*1.25*10) {
     304      284451 :                 maxPG = minPredictionGain;
     305             :             }
     306             : 
     307             :             /* LPC weighting */
     308      284451 :             if (predGain < maxPG) {
     309           0 :                 alpha = (maxPG - predGain) * (minPGfac - 1.0) / (maxPG - minPredictionGain) + 1.0;
     310             : 
     311           0 :                 alpha_loc = 1;
     312           0 :                 for (i = 0; i <= maxOrder; i++) {
     313           0 :                     xcorr_out[i] = xcorr_out[i] * alpha_loc;
     314           0 :                     alpha_loc *= alpha;
     315             :                 }
     316             : 
     317           0 :                 poly2rc(xcorr_out, rc_unq, maxOrder + 1);
     318             :             }
     319             : 
     320             :             /* PARCOR Quantization */
     321     1486427 :             for (i = 0; i < maxOrder; i++)
     322             :             {
     323     1201976 :                 iIndex = 1;
     324     1201976 :                 x_val  = rc_unq[i];
     325             : 
     326    12945984 :                 while ((iIndex < 17) && (x_val > quants_thr_tns[iIndex - 1]))
     327             :                 {
     328    11744008 :                     iIndex = (iIndex + 1);
     329             :                 }
     330     1201976 :                 rc_idx_tmp[i] = (iIndex - 2);
     331             :             }
     332             :             
     333             :             /* Filter Order */
     334      284451 :             order_tmp = 0;
     335     1486427 :             for (i = 0; i < maxOrder; i++) {
     336     1201976 :                 rc[i] = quants_pts_tns[rc_idx_tmp[i]];
     337             : 
     338     1201976 :                 if (rc[i] != 0) {
     339      994802 :                     order_tmp = i + 1;
     340             :                 }
     341             :             }
     342             : 
     343      284451 :             order_out[f] = order_tmp;
     344             : 
     345             :             /* Disable TNS if order is 0: */
     346      284451 :             if (order_out[f] == 0) {
     347           0 :                 tns = 0;
     348             : 
     349             :                 /* Jump to else statement */
     350           0 :                 goto tns_disabled;
     351             :             }
     352      284451 :             tmp = order[order_out[f] - 1];
     353             : 
     354             :             /* Huffman Coding of PARCOR coefficients */
     355     1364786 :             for (i = 0; i <= order_out[f] - 1; i++) {
     356     1080335 :                 tmp += huff_bits_tns[i][rc_idx_tmp[i]];
     357             :             }
     358             : 
     359      284451 :             bits = bits + ceil((LC3_FLOAT)tmp / 2048.0);
     360             : 
     361      284451 :             j = 0;
     362     1364786 :             for (i = f * 8; i <= f * 8 + order_out[f] - 1; i++) {
     363     1080335 :                 rc_idx[i] = rc_idx_tmp[j];
     364     1080335 :                 j++;
     365             :             }
     366             :         } else {
     367     3256523 : tns_disabled:
     368     3256523 :             order_out[f] = 0;
     369             :         }
     370             : 
     371             :         /* Filtering */
     372     3540974 :         if (tns == 1) {
     373    29450647 :             for (i = startfreq[f]; i <= stopfreq[f]; i++) {
     374    29166196 :                 s       = x[i - 1];
     375    29166196 :                 tmpSave = s;
     376             : 
     377   115613414 :                 for (j = 0; j < order_out[f] - 1; j++) {
     378    86447218 :                     tmp_fl = rc[j] * s + st[j];
     379    86447218 :                     s += rc[j] * st[j];
     380             : 
     381    86447218 :                     st[j]   = tmpSave;
     382    86447218 :                     tmpSave = tmp_fl;
     383             :                 }
     384             : 
     385    29166196 :                 s += rc[order_out[f] - 1] * st[order_out[f] - 1];
     386             : 
     387    29166196 :                 st[order_out[f] - 1] = tmpSave;
     388    29166196 :                 x[i - 1]             = s;
     389             :             }
     390             :         }
     391             :     }
     392             : 
     393     1779817 :     *tns_numfilters = numfilters;
     394     1779817 :     *bits_out       = bits;
     395     1779817 : }

Generated by: LCOV version 1.14