LCOV - code coverage report
Current view: top level - lib_lc3plus - estimate_global_gain.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 867217ee32c8e8cd2cf5aae69e60c58e00160b49 Lines: 63 136 46.3 %
Date: 2025-12-13 06:47:12 Functions: 1 1 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             : #include "options.h"
      11             : #include "wmc_auto.h"
      12             : #include "functions.h"
      13             : 
      14             : 
      15     1189311 : void processEstimateGlobalGain_fl(LC3_FLOAT x[], LC3_INT lg, LC3_INT nbitsSQ, LC3_FLOAT* gain, LC3_INT* quantizedGain,
      16             :                                   LC3_INT* quantizedGainMin, LC3_INT quantizedGainOff, LC3_FLOAT* targetBitsOff,
      17             :                                   LC3_INT* old_targetBits, LC3_INT old_specBits
      18             :                                   , LC3_INT hrmode , LC3_INT regBits, LC3PLUS_FrameDuration frame_ms
      19             : )
      20             : {
      21             : 
      22             :     LC3_INT   i, N, offset, j, iszero, fac;
      23             :     LC3_FLOAT g_min, x_max, tmp, ind, ind_min, target, ener;
      24             :     LC3_FLOAT en[MAX_LEN / 4];
      25     1189311 :     LC3_FLOAT reg_val = 4.656612873077393e-10;
      26             : #ifdef FIX_1p25_GG_EST_TUPLES
      27     1189311 :     LC3_INT tuples[1 + 4] = { -1, GG_1p25_WB_TUPLES, GG_1p25_SSWB_TUPLES, GG_1p25_SWB_TUPLES, GG_1p25_FB_TUPLES };
      28             :     LC3_INT bw_idx;
      29             : #endif 
      30             : 
      31             : #ifdef FIX_1p25_GG_EST_TUPLES  
      32             :     LC3_INT32 lg_extra;
      33     1189311 :     if (frame_ms == LC3PLUS_FRAME_DURATION_1p25MS) 
      34             :     {
      35           0 :         assert((MAX_LEN) >= ((lg / GG_1p25_MAX_TUPLES) + 1)*GG_1p25_MAX_TUPLES);   /* en size check, for 1p25ms   max tuple size*/
      36             :     }
      37             : #else 
      38             : #ifdef FIX_BOTH_1p25_TEST_NEW_GG_EST2 
      39             :     assert( (MAX_LEN / 4) >= ((8*4 + 2) / 2));   /* en size check, for 1p25ms  SSWB */
      40             : #endif 
      41             : #endif 
      42             : 
      43             : #ifdef FIX_1p25_GG_EST_TUPLES
      44     1189311 :     lg_extra = 0;    
      45     1189311 :     bw_idx = MIN((lg / 10) - 1, 4);
      46             :  
      47     1189311 :     if (frame_ms == LC3PLUS_FRAME_DURATION_1p25MS)
      48             :     {  
      49           0 :         lg_extra = tuples[bw_idx] * (( lg + (tuples[bw_idx] - 1)) / tuples[bw_idx]) - lg; 
      50             :         /*x buffer is assert checked  in enc_lc3_fl.c() for 1.25ms  energy calculation */
      51           0 :         for (i = lg; i < (lg + lg_extra); i++)
      52             :         {
      53           0 :             x[i] = 0.0; /* zero extended  tail if a truncated tuple-block exists */
      54             :         }
      55             :     }
      56             : #else 
      57             : #ifdef FIX_FLOAT_ENC_QUANTIZE_1P25MS_512KBPS
      58             :     LC3_INT32 lg_extra;
      59             :     
      60             :     lg_extra = lg - 4 * (lg / 4); 
      61             :     for ( i=lg; i< (lg+lg_extra); i++)
      62             :     {
      63             :          x[i] = 0.0; /* zero tail if a truncated quadruple exists */
      64             :     }
      65             : #endif
      66             : #endif 
      67     1189311 :     if (*old_targetBits < 0) {
      68       12165 :         *targetBitsOff = 0;
      69             :     } else {
      70     1177146 :         tmp            = MIN(40, MAX(-40, *targetBitsOff + *old_targetBits - old_specBits));
      71     1177146 :         *targetBitsOff = 0.8 * *targetBitsOff + 0.2 * tmp;
      72             :     }
      73             : 
      74     1189311 :     *old_targetBits = nbitsSQ;
      75     1189311 :     nbitsSQ         = nbitsSQ + round(*targetBitsOff);
      76             : 
      77     1189311 :     x_max = array_max_abs(x, lg);
      78             : 
      79     1189311 :     if (hrmode && regBits > 0)
      80             :     {
      81           0 :         LC3_FLOAT M0 = 1e-5, M1 = 1e-5, rB_offset;
      82           0 :         LC3_FLOAT thresh = 2*frame_ms*1.25;
      83           0 :         for (i = 0; i < lg; i++)
      84             :         {
      85           0 :                 M0 += fabs(x[i]);
      86           0 :                 M1 += i*fabs(x[i]);
      87             :         }
      88             : 
      89           0 :         rB_offset = 8 * (1 - MIN(M1/M0, thresh) / thresh);
      90           0 :         reg_val = x_max * LC3_POW(2,-regBits - rB_offset);
      91             :     }
      92             : 
      93     1189311 :     if (x_max < LC3_EPS)
      94             :     {
      95       12661 :         ind_min         = quantizedGainOff;
      96       12661 :         ind             = 0;
      97       12661 :         *old_targetBits = -1;
      98             :     }
      99             :     else {
     100     1176650 :         if (hrmode == 1) {
     101           0 :             g_min = x_max / (32768 * 256 - 2);
     102             :         }
     103             :         else {
     104     1176650 :             g_min = x_max / (32767 - 0.375);
     105             :         }
     106             :         /* Prevent positive rounding errors from LC3_LOG10 function */
     107     1176650 :         ind_min = 28.0 * LC3_LOGTEN(g_min);
     108             : 
     109     1176650 :         ind_min = ceil(ind_min + LC3_FABS(ind_min) * LC3_EPS);
     110             : 
     111     1176650 :         assert(LC3_POW(10, ind_min / 28.0) >= g_min);
     112     1176650 :         assert(ind_min <= (255 + quantizedGainOff));
     113             : 
     114             : #ifdef FIX_FLOAT_ENC_QUANTIZE_1P25MS_512KBPS
     115     1176650 :         N = lg + lg_extra;
     116             : #else 
     117             :         N = lg;
     118             : #endif
     119             : 
     120             : 
     121             : #ifndef FIX_1p25_GG_EST_TUPLES
     122             : #ifdef FIX_BOTH_1p25_TEST_NEW_GG_EST2
     123             :         /*  increase to at least 10 analysis bands for  WB, SSWB 1p25ms */
     124             :         if (frame_ms == LC3PLUS_FRAME_DURATION_1p25MS && lg <= 30)
     125             :         {
     126             :             j = 0;
     127             :             for (i = 0; i < N; i = i + 2) /* steps of 2  for 1.25ms frame lengths */
     128             :             {
     129             :                 tmp = x[i] * x[i];
     130             :                 tmp += x[i + 1] * x[i + 1];
     131             :                 en[j] = (28.0 / 20.0) * (7 * 0.5 + 10.0 * LC3_LOGTEN(tmp + reg_val)); /*  offset of 7 per 4 coeff band   now changed to 3.5 per 2 coeff band */
     132             :                 j++;
     133             :             }
     134             : 
     135             :             target = (28.0 / 20.0) * (1.4) * nbitsSQ;  /* global index domain  sum over all 10 bands  */
     136             : 
     137             :             fac = 256;
     138             :             offset = 255 + quantizedGainOff;
     139             : 
     140             :             for (i = 0; i < 8; i++)
     141             :             {
     142             :                 fac = fac >> 1;
     143             :                 offset = offset - fac;
     144             :                 ener = 0;
     145             :                 iszero = 1;
     146             : 
     147             :                 /* we sum up energy from the top,  to not add up noisefilled coeffs */
     148             :                 for (j = N / 2 - 1; j >= 0; j--)
     149             :                 {
     150             :                     tmp = en[j] - offset;
     151             : 
     152             :                     if (tmp < ((7.0) * (28.0 / 20.0) * 0.5))
     153             :                     {
     154             :                         if (iszero == 0)
     155             :                         {
     156             :                             ener = ener + ((2.7) * (28.0 / 20.0)* 0.5);  /* low cost in coded band zero */
     157             :                         }
     158             :                     }
     159             :                     else
     160             :                     {
     161             :                         if (tmp > ((50.0) * (28.0 / 20.0)*0.5))
     162             :                         {
     163             :                             /* high value with many escapes */
     164             : 
     165             :                             ener = ener + 2.0 * tmp - (50.0) * (28.0 / 20.0)*0.5;
     166             : 
     167             :                         }
     168             :                         else
     169             :                         {
     170             :                             ener = ener + (tmp*1.0);
     171             :                         }
     172             :                         iszero = 0;
     173             :                     }
     174             :                 } /* loop over over band  N/2-1 ...  0   */
     175             : 
     176             :                 if (ener > target && iszero == 0)
     177             :                 {
     178             :                     offset = offset + fac;
     179             :                 }
     180             : 
     181             :             } /* over 8 splits/iterations to handle all 256 possible shifts  */
     182             : 
     183             :             if (offset < ind_min)
     184             :             {
     185             :                 *old_targetBits = -1;
     186             :             }
     187             : 
     188             :             ind = MAX(ind_min, offset) - quantizedGainOff;
     189             :         }
     190             :         else
     191             : #endif
     192             : #endif 
     193             : 
     194             : 
     195             : 
     196             : #ifdef FIX_1p25_GG_EST_TUPLES
     197             : 
     198             : #if GG_1p25_MAX_TUPLES == 2   
     199             :             /*  the tuple/2-block  with halved limits, is here separated from the  4-block loop ,
     200             :                  optionally they can be parametrized into one function */
     201             :             if (frame_ms == LC3PLUS_FRAME_DURATION_1p25MS)
     202             : #else 
     203     1176650 :             if (frame_ms == LC3PLUS_FRAME_DURATION_1p25MS && tuples[bw_idx] == 2)
     204             : #endif 
     205             :             {
     206           0 :                 assert(((lg / 2) * 2) == lg);
     207             : 
     208           0 :                 j = 0;
     209           0 :                 for (i = 0; i < N; i = i + 2)
     210             :                 {
     211           0 :                     tmp = x[i] * x[i];
     212           0 :                     tmp += x[i + 1] * x[i + 1];
     213           0 :                     en[j] = (28.0 / 20.0) * (7 * 0.5 + 10.0 * LC3_LOGTEN(tmp + reg_val)); /*  offset of 7 per 4 coeff band   now changed to 3.5 per 2 coeff band */
     214           0 :                     j++;
     215             :                 }
     216             : 
     217           0 :                 target = (28.0 / 20.0) * (1.4) * nbitsSQ;  /* global index domain  sum over all bands  */
     218             : 
     219           0 :                 fac = 256;
     220           0 :                 offset = 255 + quantizedGainOff;
     221             : 
     222           0 :                 for (i = 0; i < 8; i++)
     223             :                 {
     224           0 :                     fac = fac >> 1;
     225           0 :                     offset = offset - fac;
     226           0 :                     ener = 0;
     227           0 :                     iszero = 1;
     228             : 
     229             :                     /* we sum up energy from the top,  to not add up noisefilled coeffs */
     230           0 :                     for (j = N / 2 - 1; j >= 0; j--)
     231             :                     {
     232           0 :                         tmp = en[j] - offset;
     233             : 
     234           0 :                         if (tmp < ((7.0) * (28.0 / 20.0) * 0.5))
     235             :                         {
     236           0 :                             if (iszero == 0)
     237             :                             {
     238           0 :                                 ener = ener + ((2.7) * (28.0 / 20.0)* 0.5);  /* low cost in coded band zero */
     239             :                             }
     240             :                         }
     241             :                         else
     242             :                         {
     243           0 :                             if (tmp > ((50.0) * (28.0 / 20.0)*0.5))
     244             :                             {
     245             :                                 /* high value with many escapes */
     246             : 
     247           0 :                                 ener = ener + 2.0 * tmp - (50.0) * (28.0 / 20.0)*0.5;
     248             : 
     249             :                             }
     250             :                             else
     251             :                             {
     252           0 :                                 ener = ener + (tmp*1.0);
     253             :                             }
     254           0 :                             iszero = 0;
     255             :                         }
     256             :                     } /* loop over over band  N/2-1 ...  0   */
     257             : 
     258           0 :                     if (ener > target && iszero == 0)
     259             :                     {
     260           0 :                         offset = offset + fac;
     261             :                     }
     262             : 
     263             :                 } /* over 8 splits/iterations to handle all 256 possible shifts  */
     264             : 
     265           0 :                 if (offset < ind_min)
     266             :                 {
     267           0 :                     *old_targetBits = -1;
     268             :                 }
     269             : 
     270           0 :                 ind = MAX(ind_min, offset) - quantizedGainOff;
     271             :             }
     272             :             else
     273             : 
     274             : #if GG_1p25_MAX_TUPLES == 3   
     275             :                 /*  the 3tuple -block  with modified  limits, is here separated from the quadruple/4-block loop ,
     276             :                      optionally they can be parametrized into one function */
     277     1176650 :                 if (frame_ms == LC3PLUS_FRAME_DURATION_1p25MS)
     278             : #else 
     279             : 
     280             :                 if (frame_ms == LC3PLUS_FRAME_DURATION_1p25MS && tuples[bw_idx] == 3)
     281             : #endif 
     282             :                 {   /* 3 tuple loop */
     283           0 :                     N = 3 * (int)ceil(lg / 3.0);
     284             : 
     285           0 :                     assert(lg == 50 || lg == 40 || lg == 30 || lg == 20);
     286           0 :                     assert(N == (17 * 3) || N == (14 * 3) || N == (10 * 3) || N == (7 * 3));
     287             : 
     288           0 :                     j = 0;
     289           0 :                     for (i = 0; i < N; i = i + 3)
     290             :                     {
     291           0 :                         tmp = x[i] * x[i];
     292           0 :                         tmp += x[i + 1] * x[i + 1];
     293           0 :                         tmp += x[i + 2] * x[i + 2];
     294           0 :                         en[j] = (28.0 / 20.0) * (7 * 0.75 + 10.0 * LC3_LOGTEN(tmp + reg_val)); /*  offset of 7*0.75  per  3 coeff band   n */
     295           0 :                         j++;
     296             :                     }
     297             : 
     298           0 :                     target = (28.0 / 20.0) * (1.4) * nbitsSQ;  /* global index domain  sum over all bands  */
     299             : 
     300           0 :                     fac = 256;
     301           0 :                     offset = 255 + quantizedGainOff;
     302             : 
     303           0 :                     for (i = 0; i < 8; i++)
     304             :                     {
     305           0 :                         fac = fac >> 1;
     306           0 :                         offset = offset - fac;
     307           0 :                         ener = 0;
     308           0 :                         iszero = 1;
     309             : 
     310             :                         /* we sum up energy from the top,  to not add up noisefilled coeffs */
     311           0 :                         for (j = N / 3 - 1; j >= 0; j--)
     312             :                         {
     313           0 :                             tmp = en[j] - offset;
     314             : 
     315           0 :                             if (tmp < ((7.0) * (28.0 / 20.0) * 0.75))
     316             :                             {
     317           0 :                                 if (iszero == 0)
     318             :                                 {
     319           0 :                                     ener = ener + ((2.7) * (28.0 / 20.0)* 0.75);  /* low cost in coded band zero */
     320             :                                 }
     321             :                             }
     322             :                             else
     323             :                             {
     324           0 :                                 if (tmp > ((50.0) * (28.0 / 20.0)*0.75))
     325             :                                 {
     326             :                                     /* high value with many escapes */
     327             : 
     328           0 :                                     ener = ener + 2.0 * tmp - (50.0) * (28.0 / 20.0)*0.75;
     329             : 
     330             :                                 }
     331             :                                 else
     332             :                                 {
     333           0 :                                     ener = ener + (tmp*1.0);
     334             :                                 }
     335           0 :                                 iszero = 0;
     336             :                             }
     337             :                         } /* loop over over band  N/3-1 ...  0   */
     338             : 
     339           0 :                         if (ener > target && iszero == 0)
     340             :                         {
     341           0 :                             offset = offset + fac;
     342             :                         }
     343             : 
     344             :                     } /* over 8 splits/iterations to handle all 256 possible shifts  */
     345             : 
     346           0 :                     if (offset < ind_min)
     347             :                     {
     348           0 :                         *old_targetBits = -1;
     349             :                     }
     350             : 
     351           0 :                     ind = MAX(ind_min, offset) - quantizedGainOff;
     352             :                 }
     353             :                 else
     354             : 
     355             : #endif /* end  2, 3  tuple loops */
     356             : 
     357             : #ifdef FIX_1p25_GG_EST_TUPLES
     358             :                 {  /* brackets for 4 tuple loop */
     359     1176650 :                     assert((((lg + lg_extra) / 4) * 4) == (lg + lg_extra));
     360             : #endif
     361             : #ifndef FIX_1p25_GG_EST_TUPLES
     362             : #ifdef FIX_BOTH_1p25_TEST_NEW_GG_EST2 
     363             :                     {
     364             : #endif
     365             : #endif 
     366             : 
     367     1176650 :                         j = 0;
     368    62501950 :                         for (i = 0; i < N; i = i + 4) {
     369    61325300 :                             tmp = x[i] * x[i];
     370    61325300 :                             tmp += x[i + 1] * x[i + 1];
     371    61325300 :                             tmp += x[i + 2] * x[i + 2];
     372    61325300 :                             tmp += x[i + 3] * x[i + 3];
     373    61325300 :                             en[j] = (28.0 / 20.0) * (7 + 10.0 * LC3_LOGTEN(tmp + reg_val));
     374    61325300 :                             j++;
     375             :                         }
     376             : 
     377     1176650 :                         target = (28.0 / 20.0) * (1.4) * nbitsSQ;
     378     1176650 :                         fac = 256;
     379     1176650 :                         offset = 255 + quantizedGainOff;
     380             : 
     381    10589850 :                         for (i = 0; i < 8; i++)
     382             :                         {
     383     9413200 :                             fac = fac >> 1;
     384     9413200 :                             offset = offset - fac;
     385     9413200 :                             ener = 0;
     386     9413200 :                             iszero = 1;
     387             : 
     388   500015600 :                             for (j = N / 4 - 1; j >= 0; j--) {
     389   490602400 :                                 tmp = en[j] - offset;
     390             : 
     391   490602400 :                                 if (tmp < (7.0) * (28.0 / 20.0)) {
     392    37512870 :                                     if (iszero == 0) {
     393    24543181 :                                         ener = ener + (2.7) * (28.0 / 20.0);
     394             :                                     }
     395             :                                 }
     396             :                                 else {
     397   453089530 :                                     if (tmp > (50.0) * (28.0 / 20.0)) {
     398    94304653 :                                         ener = ener + 2.0 * tmp - (50.0) * (28.0 / 20.0);
     399             :                                     }
     400             :                                     else {
     401   358784877 :                                         ener = ener + tmp;
     402             :                                     }
     403             : 
     404   453089530 :                                     iszero = 0;
     405             :                                 }
     406             :                             }
     407             : 
     408     9413200 :                             if (ener > target && iszero == 0) {
     409     5133114 :                                 offset = offset + fac;
     410             :                             }
     411             :                         }
     412             : 
     413     1176650 :                         if (offset < ind_min) {
     414          72 :                             *old_targetBits = -1;
     415             :                         }
     416             : 
     417     1176650 :                         ind = MAX(ind_min, offset) - quantizedGainOff;
     418             :                 }
     419             : #ifdef FIX_1p25_GG_EST_TUPLES
     420             :     }
     421             :   /* end bracket for 4 tuple loop */
     422             : #else 
     423             : #ifdef FIX_BOTH_1p25_TEST_NEW_GG_EST2 
     424             :     }
     425             : #endif
     426             : #endif
     427             : 
     428     1189311 :     *quantizedGainMin = ind_min;
     429     1189311 :     *quantizedGain = ind;
     430             : 
     431     1189311 :     *gain = LC3_POW(10.0, ((ind + quantizedGainOff) / 28.0));
     432     1189311 : }

Generated by: LCOV version 1.14