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

          Line data    Source code
       1             : /******************************************************************************
       2             : *                        ETSI TS 103 634 V1.5.1                               *
       3             : *              Low Complexity Communication Codec Plus (LC3plus)              *
       4             : *                                                                             *
       5             : * Copyright licence is solely granted through ETSI Intellectual Property      *
       6             : * Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
       7             : * estoppel or otherwise.                                                      *
       8             : ******************************************************************************/
       9             : 
      10             : #include "options.h"
      11             : #include "wmc_auto.h"
      12             : #include "defines.h"
      13             : #include "functions.h"
      14             : 
      15             : #define BETA_MUTE_FAC 0.5                            /*  % attenuation factor per additional bad frame, FX uses 0.5 (shift right with 1 bit) */
      16             : #define BETA_MUTE_FAC_INI 0.5
      17             : #define OFF_FRAMES_LIMIT 30                          /*   300 ms for LC3 10 ms   */
      18             : #define LGW32k 7
      19             : #define LGW16k 5
      20             : 
      21             : /*  Tables for attentuation of mag_chg, copied from FX */
      22             : /*  Tables are in Q15 */
      23             : /*   0.3 dB attenuation per frame for 16 frames, then 6 dB attenuation per frame */
      24             : const LC3_INT32 POW_ATT_TABLE1[OFF_FRAMES_LIMIT + 1] = { 32767, 31656, 30581, 29543, 28540, 27571, 26635, 25731, 24857, 24013,
      25             :                                                     23198, 22410, 21650, 20915, 20205, 19519,  9759,  4880,  2440,  1220,
      26             :                                                       610,   305,   152,    76,    38,    19,    10,     5,     2,     1,
      27             :                                                         0 };
      28             : /* % 0.4 dB attenuation per frame for 16 frames, then 6 dB attenuation per frame */
      29             : const LC3_INT32 POW_ATT_TABLE0[OFF_FRAMES_LIMIT + 1] = { 32767, 31293, 29885, 28540, 27255, 26029, 24857, 23738, 22670, 21650,
      30             :                                                     20675, 19745, 18856, 18007, 17197, 16423,  8211,  4106,  2053,  1026,
      31             :                                                       513,   257,   128,    64,    32,    16,     8,     4,     2,     1,
      32             :                                                         0 };
      33             : 
      34             : #ifdef PLC2_FADEOUT_IN_MS 
      35             : #if PLC2_FADEOUT_IN_MS == 0
      36             : #else 
      37             : 
      38             : const LC3_INT32 POW_ATT_TABLE_p3x9_14_7[OFF_FRAMES_LIMIT + 1] = {
      39             :  32767,
      40             :  31656,  30581,  29543,  28540,  27571,  26635,  25731,  24857,   24013,  /* 9 times .3dB steps , 14  6 dB steps, 7 muted steps */
      41             :   12007,   6003,    3002,    1501,    750,    375,     188,     94,     47,      23, 12, 6,      3,      1,
      42             :   0,      0,      0,      0,      0,      0,  0 };
      43             : 
      44             : const LC3_INT32 POW_ATT_TABLE_p4x9_14_7[OFF_FRAMES_LIMIT + 1] =
      45             : { 32767,
      46             :   31293, 29885, 28540, 27255, 26029, 24857, 23738, 22670, 21650,  /* 9 times .4dB steps  , 14  6 dB steps, 7 muted steps */
      47             :   10825, 5413,  2706,  1353,  677,   338,  169,  85,  42, 21, 11, 5, 3, 1,
      48             :    0, 0,0,0,0,0,0 };
      49             : 
      50             : const LC3_INT32 POW_ATT_TABLE_p3x8_6[] = {
      51             :  32767,  31656,  30581,  29543,  28540,  27571,  26635,  25731,  12865,   6433,
      52             :   3216,   1608,    804,    402,    201,    101,     50,     25,     13,      6,
      53             :      3,      2,      1,      0,      0,      0,      0,      0,      0,      0,  0 };
      54             : const LC3_INT32  POW_ATT_TABLE_p4x8_6[OFF_FRAMES_LIMIT + 1] = {
      55             :  32767,  31293,  29885,  28540,  27255,  26029,  24857,  23738,  11869,   5935,
      56             :   2967,   1484,    742,    371,    185,     93,     46,     23,     12,      6,
      57             :      3,      1,      1,      0,      0,      0,      0,      0,      0,      0,  0 };
      58             : 
      59             : const LC3_INT32  POW_ATT_TABLE_p3x4_6[OFF_FRAMES_LIMIT + 1] = {
      60             :  32767,  31656,  30581,  29543,  14772,   7386,   3693,   1847,    923,    462,
      61             :    231,    115,     58,     29,     14,      7,      4,      2,      1,      0,
      62             :      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,  0 };
      63             : const LC3_INT32  POW_ATT_TABLE_p4x4_6[OFF_FRAMES_LIMIT + 1] = {
      64             :  32767,  31293,  29885,  28540,  14270,   7135,   3568,   1784,    892,    446,
      65             :    223,    111,     56,     28,     14,      7,      3,      2,      1,      0,
      66             :      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,     0 };
      67             : 
      68             : const LC3_INT32  POW_ATT_TABLE_p3x2_6[OFF_FRAMES_LIMIT + 1] = {
      69             :  32767,  31656,  15828,   7914,   3957,   1979,    989,    495,    247,    124,
      70             :     62,     31,     15,      8,      4,      2,      1,      0,      0,      0,
      71             :      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,     0 };
      72             : const LC3_INT32  POW_ATT_TABLE_p4x2_6[OFF_FRAMES_LIMIT + 1] = {
      73             :  32767,  31293,  15647,   7823,   3912,   1956,    978,    489,    244,    122,
      74             :     61,     31,     15,      8,      4,      2,      1,      0,      0,      0,
      75             :      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,     0 };
      76             : 
      77             : const LC3_INT32  POW_ATT_TABLE_p3x1_6[OFF_FRAMES_LIMIT + 1] = {
      78             :  32767,  16384,   8192,   4096,   2048,   1024,    512,    256,    128,     64,
      79             :     32,     16,      8,      4,      2,      1,      1,      0,      0,      0,
      80             :      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,     0 };
      81             : const LC3_INT32  POW_ATT_TABLE_p4x1_6[OFF_FRAMES_LIMIT + 1] = {
      82             :  32767,  16384,   8192,   4096,   2048,   1024,    512,    256,    128,     64,
      83             :     32,     16,      8,      4,      2,      1,      1,      0,      0,      0,
      84             :      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,     0 };
      85             : 
      86             : const LC3_INT32 *const POW_ATT_TABLES[1 + 12] =
      87             : { NULL,
      88             : /*0.3dB col      ,      0.4dB col */
      89             : /* 1*/POW_ATT_TABLE_p3x1_6, POW_ATT_TABLE_p4x1_6,       /* 0 0.3dB,  16 6dB, 14mute   */ /*  0.4dB version */  /* old short mute tabs  */
      90             : /* 3*/POW_ATT_TABLE_p3x2_6, POW_ATT_TABLE_p4x2_6,       /* 1 0.3dB,  15 6dB ,14mute   */ /* 0.4dB version  */
      91             : /* 5*/POW_ATT_TABLE_p3x4_6, POW_ATT_TABLE_p4x4_6,       /* 3 0.3dB,  15 6dB , 12 mute */ /* 0.4dB version  */
      92             : /* 7*/POW_ATT_TABLE_p3x8_6, POW_ATT_TABLE_p4x8_6,       /* 7 0.3dB,  15 6dB , 8 mute  */ /* 0.4dB version  */
      93             : /* 9*/POW_ATT_TABLE_p3x9_14_7, POW_ATT_TABLE_p4x9_14_7, /* 9 0.3dB,  14 6dB , 7 mute  */ /* 0.4dB version  */   /* opt 120 ms */
      94             : /*11*/POW_ATT_TABLE1,       POW_ATT_TABLE0,             /* 15 0.3dB, 14 6dB , 1 mute */  /* 0.4dB version  */   /*  original   curves */
      95             : };
      96             : 
      97             : #endif
      98             : #endif
      99             : 
     100           0 : void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *grp_pow_change,  
     101             :                           LC3_FLOAT *stPhECU_beta_mute, LC3_FLOAT *stPhECU_mag_chg_1st,
     102             :                           LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_FLOAT *ph_dith, LC3_INT32 *tr_dec,
     103             :                           LC3_FLOAT *att_val, LC3_INT32 *attDegreeFrames_dbg, LC3_FLOAT *thresh_dbg                         
     104             :                               , LC3_UINT8 plc_fadeout_type
     105             :                           ) 
     106             : {
     107             : 
     108             :     LC3_INT32 i;
     109             :     LC3_FLOAT  thresh_tr_dB, max_increase_grp_pow;
     110             :     LC3_FLOAT max_increase_grp_pow_lin;
     111             :     LC3_FLOAT grp_pow_change_lin[MAX_LGW];
     112             :     LC3_FLOAT XavgFadeinFactor;
     113             : 
     114             :     LC3_INT32 burst_att_thresh;
     115             :     LC3_INT32 att_per_frame_idx;
     116             :     LC3_INT32 att_always,   attDegreeFrames;
     117             :     const LC3_INT32 *TABLEQ15;
     118             :     LC3_INT32 beta_mute_thr;                             /* time threshold in 10 ms frames  to start beta - noise attenuation */
     119             :     UNUSED(attDegreeFrames_dbg);
     120             : 
     121             :     /* constants setup */
     122           0 :     att_always = 0;  
     123             : 
     124           0 :     XavgFadeinFactor = -1.0;
     125             : 
     126             :     /* 10ms constants */
     127           0 :     thresh_tr_dB = 10.0;            /*    dB threshold kept same as for 20ms, even though transient analysis frame size was shortened */
     128           0 :     max_increase_grp_pow = 0;      /*     maximum amplification(dB)  in case of onset transients, offset always deacy */
     129             : 
     130           0 :     max_increase_grp_pow_lin = (LC3_FLOAT)1.0*LC3_POW((LC3_FLOAT)10.0, max_increase_grp_pow / (LC3_FLOAT)10.0)*(LC3_FLOAT)(32767.0 / 32768.0);
     131             : 
     132           0 :     if (plc_fadeout_type != 0)
     133             :     {
     134           0 :         i = (PLC2_FADEOUT_LONG_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES;   /*a long fading table entry in fade_scheme_tab  */
     135             :     } else {
     136           0 :         i = (PLC2_FADEOUT_IN_MS - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES;   /* a shorter  fading entry in  fade_scheme_tab  */
     137             :     }
     138           0 :     assert(i >= 0 && i <= ((PLC2_FADEOUT_IN_MS_MAX - PLC2_FADEOUT_IN_MS_MIN) / PLC2_FADEOUT_RES) && "fade_scheme_tab index error");
     139             : 
     140           0 :     att_per_frame_idx = fade_scheme_tab[i][0];
     141           0 :     burst_att_thresh  = fade_scheme_tab[i][1];           /* number of 1.0 frames before  muting/mixing phase */
     142             :     /* band gain muting may can take place earlier due to a band transient */
     143           0 :     beta_mute_thr = fade_scheme_tab[i][2];          /*   muting of Xavg contribution  start when slow fadeout is over */
     144             :  
     145           0 :     attDegreeFrames = 0;
     146           0 :     if (burst_len > burst_att_thresh)
     147             :     {
     148           0 :         att_always = 1;
     149             : 
     150             :         /*   Added to be able to able to use tables to be aligned with FX */
     151             :         /*   Limit attDegreeFrames to OFF_FRAMES_LIMIT */
     152           0 :         attDegreeFrames = burst_len - burst_att_thresh;
     153             : 
     154           0 :         if (attDegreeFrames > OFF_FRAMES_LIMIT)
     155             :         {
     156           0 :             attDegreeFrames = OFF_FRAMES_LIMIT;
     157             :         }
     158             :     }
     159             : 
     160             : 
     161           0 :     set_vec(1.0 * (32767.0/32768.0), mag_chg, n_grp);
     162           0 :     set_vec(0.0, ph_dith, n_grp);
     163             : 
     164           0 :     set_vec(1.0 * (32767.0/32768.0), alpha, n_grp);
     165           0 :     set_vec(0.0, beta, n_grp);
     166           0 :     set_vec_int(0, tr_dec, n_grp);
     167             : 
     168           0 :     set_vec(1.0 * (32767.0/32768.0), att_val, n_grp);
     169             : 
     170             :  
     171             : 
     172             :     /* transient detection per band  */
     173           0 :     for (i = 0;i < n_grp; i++) {
     174           0 :         if(burst_len == 1)
     175             :         {
     176             :             /* first bad frame  */
     177           0 :             grp_pow_change_lin[i] = LC3_POW((LC3_FLOAT)10.0, grp_pow_change[i]/(LC3_FLOAT)10.0);
     178             : 
     179           0 :             *stPhECU_beta_mute = BETA_MUTE_FAC_INI;
     180           0 :             *stPhECU_beta_mute = *stPhECU_beta_mute / (LC3_FLOAT)2.0;
     181             :              
     182             :             /*  transient processing */
     183             :             /*   transients may be both rise and decay transients !! */
     184             : 
     185           0 :             if(LC3_FABS(grp_pow_change[i]) >= thresh_tr_dB)
     186             :             {
     187             :  
     188           0 :                 tr_dec[i] = 1;
     189             :             }
     190             : 
     191             : 
     192             :             /*   magnitude modification */
     193           0 :             att_val[i] = 0.0f;
     194           0 :             if(tr_dec[i] || att_always) {
     195             : 
     196           0 :                 att_val[i] = MIN(max_increase_grp_pow_lin, grp_pow_change_lin[i]);  /*  % linear values !! */
     197           0 :                 att_val[i] = LC3_SQRT(att_val[i]);
     198           0 :                 mag_chg[i] = att_val[i];
     199           0 :                 stPhECU_mag_chg_1st[i] = att_val[i];
     200             :             }
     201             :             else
     202             :             {
     203           0 :                 mag_chg[i] = 1.0 * (LC3_FLOAT)(32767.0/32768.0);
     204           0 :                 stPhECU_mag_chg_1st[i] = (LC3_FLOAT)1.0;
     205             :             }
     206             :         }
     207             :         else
     208             :         {
     209             :             /*   burst handling based on states */
     210             : 
     211           0 :             assert(burst_len >= 2);      /*  states used here */
     212           0 :             tr_dec[i] = 0;
     213             : 
     214             :             {
     215           0 :                 assert(att_per_frame_idx >= 1 && att_per_frame_idx <= (10+2));
     216           0 :                 TABLEQ15 = POW_ATT_TABLES[att_per_frame_idx]; 
     217           0 :                 att_val[i] = (LC3_FLOAT)1.0 * ( (LC3_FLOAT) TABLEQ15[MIN(OFF_FRAMES_LIMIT, attDegreeFrames )]  / (LC3_FLOAT)32768.0);  /* Table idx 0...N-1 therefore no + 1 */
     218           0 :                 att_val[i] = att_val[i];
     219             :             }
     220             :                         
     221           0 :             if ( (att_val[i] != 0) && (att_val[i] * (LC3_FLOAT)32768.0 < (LC3_FLOAT)0.5) )
     222             :             {
     223           0 :                 att_val[i] = 0.0;            /*   for SNR measurments match in  float lowest possible level to BASOP representation  */
     224             :             }
     225             : 
     226             :             /*  Apply attenuation */
     227           0 :             mag_chg[i] = stPhECU_mag_chg_1st[i];
     228             : 
     229           0 :             mag_chg[i] = mag_chg[i] * att_val[i]; /*   add additional attenuation from burst attenation  logic */
     230             : 
     231           0 :             if ((mag_chg[i] != 0) && (mag_chg[i] * (LC3_FLOAT)32768.0 < (LC3_FLOAT)0.5))
     232             :             {
     233           0 :                 mag_chg[i] = 0;             /*   for SNR measurments match in  float lowest possible level to BASOP representation */
     234             :             }
     235             : 
     236             :             /* note beta_mute decreased once per frame,  not once per band  */
     237           0 :             if (i == 0 && burst_len > beta_mute_thr)
     238             :             {
     239           0 :                     *stPhECU_beta_mute = *stPhECU_beta_mute * (LC3_FLOAT)BETA_MUTE_FAC;
     240             :             }
     241             : 
     242           0 :             alpha[i] = mag_chg[i];
     243             : 
     244           0 :             if (alpha[i] >= (LC3_FLOAT)(32766.0 / 32768.0))
     245             :             {
     246           0 :                 beta[i] = 0;  /*  align to BASOP more efficent  use of beta */
     247             :             }
     248             :             else
     249             :             {
     250           0 :                 beta[i] = LC3_SQRT((LC3_FLOAT)1.0 - alpha[i]* alpha[i]) * *stPhECU_beta_mute;
     251             :             }
     252             : 
     253           0 :             if ( i >= LGW32k-1) {
     254           0 :                 beta[i] = beta[i] * (LC3_FLOAT)0.1;
     255             :             }
     256           0 :             else if( i >= LGW16k-1)
     257             :             {
     258           0 :                 beta[i] = beta[i] * (LC3_FLOAT)0.5;
     259             :             }
     260             : 
     261             : 
     262             :             /*  limit Xavg noise contribution further in case of offset / tr_decay */
     263             : 
     264           0 :             if ((burst_len <= burst_att_thresh) && (stPhECU_mag_chg_1st[i] < (LC3_FLOAT)(32767.0 / 32768.0)))
     265             :             {
     266           0 :                XavgFadeinFactor = (LC3_FLOAT)(burst_len - (LC3_FLOAT)1.0) / burst_att_thresh;
     267             :         
     268           0 :                XavgFadeinFactor = MIN((LC3_FLOAT)1.0, XavgFadeinFactor);
     269             : 
     270           0 :                beta[i] = beta[i] * XavgFadeinFactor;
     271             :   
     272             :             }
     273             :         }
     274             :     }
     275             : 
     276           0 :     if (thresh_dbg != NULL)
     277             :     {
     278           0 :         *thresh_dbg = XavgFadeinFactor;
     279             :     }
     280             : 
     281           0 :      return;
     282             : }
     283             : 

Generated by: LCOV version 1.14