LCOV - code coverage report
Current view: top level - lib_lc3plus - tns_coder.c (source / functions) Hit Total Coverage
Test: Coverage on main -- conformance test test_26252.py @ a21f94bc6bac334fe001a5bad2f7b32b79038097 Lines: 133 195 68.2 %
Date: 2025-11-01 05:07:43 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     2417465 : void xcorr(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT lag, LC3_INT inLen)
      19             : {
      20             :         LC3_INT32   m;
      21             : 
      22             : 
      23    15276306 :     for (m = 0; m <= lag; m++) {
      24             :         /* Calculate correlation */
      25    12858841 :         out[m] = mac_loop(in, &in[m], (inLen - m));
      26             :     }
      27     2417465 : }
      28             : 
      29     1178514 : 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     1178514 :     g          = r[1] / r[0];
      35     1178514 :     out_lev[0] = g;
      36             : 
      37     1178514 :     v         = (1.0 - g * g) * r[0];
      38     1178514 :     rc_unq[0] = -g;
      39             : 
      40     4971484 :     for (t = 1; t < len; t++) {
      41             : 
      42     3792970 :         sum = 0;
      43    12279908 :         for (i = 1; i <= t; i++) {
      44     8486938 :             sum += out_lev[i - 1] * r[i];
      45             :         }
      46             : 
      47     3792970 :         g = (r[t + 1] - sum) / v;
      48             : 
      49     3792970 :         j = 1;
      50    12279908 :         for (i = t - 1; i >= 0; i--) {
      51     8486938 :             buf_tmp[j] = out_lev[j - 1] - g * out_lev[i];
      52     8486938 :             j++;
      53             :         }
      54             : 
      55     3792970 :         move_float(&out_lev[1], &buf_tmp[1], len);
      56             : 
      57     3792970 :         out_lev[0] = g;
      58             : 
      59     3792970 :         v         = v * (1 - g * g);
      60     3792970 :         rc_unq[t] = -g;
      61             :     }
      62             : 
      63             :     /* Reorder out_lev */
      64     1178514 :     out_lev[0] = 1;
      65     1178514 :     j          = 1;
      66     6149998 :     for (i = len - 1; i >= 0; i--) {
      67     4971484 :         buf_tmp[j] = -out_lev[i];
      68     4971484 :         j++;
      69             :     }
      70             : 
      71     1178514 :     move_float(&out_lev[1], &buf_tmp[1], (len - 1));
      72             : 
      73     1178514 :     out_lev[len] = rc_unq[len - 1];
      74             : 
      75     1178514 :     *error = v;
      76     1178514 : }
      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      590506 : 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      590506 :           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      590506 :     if (fs >= 32000 && frame_dms >= LC3PLUS_FRAME_DURATION_5MS) {
     163      590506 :         numfilters = 2;
     164             :     } else {
     165           0 :         numfilters = 1;
     166             :     }
     167             : 
     168             :     /* 40 * frame_dms / 10 = 4 * frame_dms */
     169      590506 :     if (N > 40 * ((LC3_FLOAT) (frame_dms*1.25*10) / 10.0)) {
     170      590506 :         N  = 40 * ((LC3_FLOAT) (frame_dms*1.25*10) / 10.0);
     171      590506 :         fs = 40000;
     172             :     }
     173             : 
     174      590506 :     if (numfilters == 1) {
     175           0 :         startfreq[0] = floor(600 * N * 2 / fs) + 1;
     176           0 :         stopfreq[0]  = N;
     177             :     } else {
     178      590506 :         startfreq[0] = floor(600 * N * 2 / fs) + 1;
     179      590506 :         startfreq[1] = N / 2 + 1;
     180      590506 :         stopfreq[0]  = N / 2;
     181      590506 :         stopfreq[1]  = N;
     182             :     }
     183             :     
     184      590506 :     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           0 :         case LC3PLUS_FRAME_DURATION_2p5MS:
     193           0 :             maxOrder      = 4;
     194           0 :             nSubdivisions = 2.0;
     195           0 :             break;
     196      558314 :         case LC3PLUS_FRAME_DURATION_5MS:
     197      558314 :             maxOrder      = 4;
     198      558314 :             nSubdivisions = 2.0;
     199      558314 :             break;
     200           0 :         case LC3PLUS_FRAME_DURATION_7p5MS:
     201           0 :             maxOrder      = 8;
     202           0 :             nSubdivisions = 3;
     203           0 :             break;
     204       32192 :         case LC3PLUS_FRAME_DURATION_10MS:
     205       32192 :             maxOrder      = 8;
     206       32192 :             nSubdivisions = 3.0;
     207       32192 :             break;
     208           0 :         case LC3PLUS_FRAME_DURATION_UNDEFINED:
     209           0 :             assert(0);
     210             :     }
     211             : 
     212      590506 :     minPredictionGain = 1.5;
     213             : 
     214      590506 :     if (nBits >= 4.8 * ((LC3_FLOAT) frame_dms * 1.25 * 10)) {
     215      590506 :         order = order1_tns;
     216             :     } else {
     217           0 :         order = order2_tns;
     218             :     }
     219             :     
     220             :     /* Processing */
     221      590506 :     if (bw_cutoff_idx >= 3 && numfilters == 2) {
     222      588008 :         numfilters   = 2;
     223      588008 :         startfreq[1] = bw_fcbin / 2 + 1;
     224      588008 :         stopfreq[0]  = bw_fcbin / 2;
     225      588008 :         stopfreq[1]  = bw_fcbin;
     226             :     } else {
     227        2498 :         numfilters  = 1;    
     228        2498 :         stopfreq[0] = bw_fcbin;
     229             :     }
     230             : 
     231      590506 :     bits = 0;
     232             : 
     233     1769020 :     for (f = 0; f < numfilters; f++) {
     234     1178514 :         subdiv_len = ((LC3_FLOAT)stopfreq[f] + 1.0 - (LC3_FLOAT)startfreq[f]) / nSubdivisions;
     235             : 
     236     1178514 :         zero_float(r, MAXLAG+1);
     237             : 
     238     3595979 :         for (sub = 1; sub <= nSubdivisions; sub++) {
     239     2419393 :             subdiv_startfreq = floor(subdiv_len * (sub - 1)) + startfreq[f] - 1;
     240     2419393 :             subdiv_stopfreq  = floor(subdiv_len * sub) + startfreq[f] - 1;
     241             :             
     242     2419393 :             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     2419393 :             sum = 0;
     266   122154241 :             for (i = subdiv_startfreq; i < subdiv_stopfreq; i++) {
     267   119734848 :                 sum += x[i] * x[i];
     268             :             }
     269             : 
     270     2419393 :             if (sum < LC3_EPS) {
     271        1928 :                 zero_float(r, MAXLAG+1);
     272        1928 :                 r[0] = 1;
     273        1928 :                 break;
     274             :             }
     275             : 
     276     2417465 :             xcorr(&x[subdiv_startfreq], xcorr_out, maxOrder, subdiv_stopfreq - subdiv_startfreq);
     277             : 
     278     2417465 :             inv_sum = 1.0 / sum;
     279    15276306 :             for (i = 0; i <= maxOrder; i++) {
     280    12858841 :                 r[i] = r[i] + xcorr_out[i] * inv_sum;
     281             :             }
     282             :         }
     283             : 
     284     7328512 :         for (i = 0; i <= maxOrder; i++) {
     285     6149998 :             r[i] = r[i] * lagw_tns[i];
     286             :         }
     287             : 
     288     1178514 :         levinsonDurbin(r, xcorr_out, rc_unq, &error_lev, maxOrder);
     289             : 
     290     1178514 :         predGain = r[0] / error_lev;
     291             : 
     292     1178514 :         if (predGain > minPredictionGain && near_nyquist_flag == 0) {
     293       13810 :             tns = 1;
     294             :         } else {
     295     1164704 :             tns = 0;
     296             :         }
     297             : 
     298     1178514 :         bits++;
     299             : 
     300     1178514 :         if (tns == 1) {
     301       13810 :             minPGfac = 0.85;
     302       13810 :             maxPG    = 2;
     303       13810 :             if (nBits >= 4.8 * frame_dms*1.25*10) {
     304       13810 :                 maxPG = minPredictionGain;
     305             :             }
     306             : 
     307             :             /* LPC weighting */
     308       13810 :             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       72006 :             for (i = 0; i < maxOrder; i++)
     322             :             {
     323       58196 :                 iIndex = 1;
     324       58196 :                 x_val  = rc_unq[i];
     325             : 
     326      606440 :                 while ((iIndex < 17) && (x_val > quants_thr_tns[iIndex - 1]))
     327             :                 {
     328      548244 :                     iIndex = (iIndex + 1);
     329             :                 }
     330       58196 :                 rc_idx_tmp[i] = (iIndex - 2);
     331             :             }
     332             :             
     333             :             /* Filter Order */
     334       13810 :             order_tmp = 0;
     335       72006 :             for (i = 0; i < maxOrder; i++) {
     336       58196 :                 rc[i] = quants_pts_tns[rc_idx_tmp[i]];
     337             : 
     338       58196 :                 if (rc[i] != 0) {
     339       44219 :                     order_tmp = i + 1;
     340             :                 }
     341             :             }
     342             : 
     343       13810 :             order_out[f] = order_tmp;
     344             : 
     345             :             /* Disable TNS if order is 0: */
     346       13810 :             if (order_out[f] == 0) {
     347           0 :                 tns = 0;
     348             : 
     349             :                 /* Jump to else statement */
     350           0 :                 goto tns_disabled;
     351             :             }
     352       13810 :             tmp = order[order_out[f] - 1];
     353             : 
     354             :             /* Huffman Coding of PARCOR coefficients */
     355       63730 :             for (i = 0; i <= order_out[f] - 1; i++) {
     356       49920 :                 tmp += huff_bits_tns[i][rc_idx_tmp[i]];
     357             :             }
     358             : 
     359       13810 :             bits = bits + ceil((LC3_FLOAT)tmp / 2048.0);
     360             : 
     361       13810 :             j = 0;
     362       63730 :             for (i = f * 8; i <= f * 8 + order_out[f] - 1; i++) {
     363       49920 :                 rc_idx[i] = rc_idx_tmp[j];
     364       49920 :                 j++;
     365             :             }
     366             :         } else {
     367     1164704 : tns_disabled:
     368     1164704 :             order_out[f] = 0;
     369             :         }
     370             : 
     371             :         /* Filtering */
     372     1178514 :         if (tns == 1) {
     373     1414828 :             for (i = startfreq[f]; i <= stopfreq[f]; i++) {
     374     1401018 :                 s       = x[i - 1];
     375     1401018 :                 tmpSave = s;
     376             : 
     377     5220518 :                 for (j = 0; j < order_out[f] - 1; j++) {
     378     3819500 :                     tmp_fl = rc[j] * s + st[j];
     379     3819500 :                     s += rc[j] * st[j];
     380             : 
     381     3819500 :                     st[j]   = tmpSave;
     382     3819500 :                     tmpSave = tmp_fl;
     383             :                 }
     384             : 
     385     1401018 :                 s += rc[order_out[f] - 1] * st[order_out[f] - 1];
     386             : 
     387     1401018 :                 st[order_out[f] - 1] = tmpSave;
     388     1401018 :                 x[i - 1]             = s;
     389             :             }
     390             :         }
     391             :     }
     392             : 
     393      590506 :     *tns_numfilters = numfilters;
     394      590506 :     *bits_out       = bits;
     395      590506 : }

Generated by: LCOV version 1.14