LCOV - code coverage report
Current view: top level - lib_lc3plus - plc_damping_scrambling_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 0 174 0.0 %
Date: 2025-08-23 01:22:27 Functions: 0 2 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 "defines.h"
      11             : #include "functions.h"
      12             : 
      13           0 : void processPLCDampingScrambling_main_fx(Word16 bfi, Word16 concealMethod, Word16 ns_nbLostFramesInRow, Word16 *cum_fflcAtten,
      14             :                                          Word16 pc_nbLostFramesInRow, Word16 *ns_seed, Word16 *pc_seed, Word16 pitch_present_bfi1,
      15             :                                          Word16 pitch_present_bfi2, Word32 spec[], Word16 *q_fx_exp, Word16 *q_old_d_fx,
      16             :                                          Word16 *q_old_fx_exp, Word16 L_spec, Word16 stabFac, Word16 frame_dms,
      17             :                                          Word16 *cum_fading_slow, Word16 *cum_fading_fast, Word16 spec_inv_idx
      18             :                                          , UWord8 plc_fadeout_type                  
      19             :                                          )
      20             : {
      21             :     Dyn_Mem_Deluxe_In(
      22             :                       Word16 processDampScramb;
      23             :                       );
      24             : 
      25           0 :     IF ( bfi != 0 )
      26             :     {
      27           0 :         processDampScramb = 0;  move16();
      28           0 :         test();
      29           0 :         IF (sub(concealMethod, LC3_CON_TEC_NS_ADV) == 0 || sub(bfi, 2) == 0)
      30             :         {
      31           0 :             processDampScramb = 1;  move16();
      32             :         }
      33             :         
      34           0 :         IF (sub(ns_nbLostFramesInRow, 1) == 0)
      35             :         {
      36           0 :             *cum_fading_slow = 32767;  move16();
      37           0 :             *cum_fading_fast = 32767;  move16();
      38           0 :             *cum_fflcAtten   = 32767;  move16();
      39             :         }
      40             :         
      41           0 :         IF (sub(bfi, 1) == 0)
      42             :         {
      43           0 :             processPLCDampingScrambling_fx(spec, L_spec, ns_nbLostFramesInRow, stabFac,
      44             :                                            processDampScramb, cum_fflcAtten,
      45             :                                            pitch_present_bfi1, frame_dms, cum_fading_slow,
      46             :                                            cum_fading_fast, ns_seed, 0
      47             :                                            , plc_fadeout_type                  
      48             :                                           );
      49             :         }
      50             :         ELSE /* bfi == 2 */
      51             :         {
      52           0 :             processPLCDampingScrambling_fx(spec, L_spec, pc_nbLostFramesInRow, stabFac,
      53             :                                            processDampScramb, cum_fflcAtten,
      54             :                                            pitch_present_bfi2, frame_dms, cum_fading_slow,
      55             :                                            cum_fading_fast, pc_seed, spec_inv_idx
      56             :                                            , plc_fadeout_type                  
      57             :                                           );
      58             : 
      59           0 :             processPLCupdateSpec_fx(q_old_d_fx, q_old_fx_exp, spec, q_fx_exp, L_spec);
      60             :         }
      61             :     }
      62             :     Dyn_Mem_Deluxe_Out();
      63           0 : }
      64             : 
      65           0 : void processPLCDampingScrambling_fx(Word32 spec[], Word16 L_spec, Word16 nbLostFramesInRow, Word16 stabFac, Word16 processDampScramb,
      66             :                                     Word16 *cum_fflcAtten, Word16 pitch_present, Word16 frame_dms, Word16 *cum_fading_slow,
      67             :                                     Word16 *cum_fading_fast, Word16 *seed, Word16 spec_inv_idx
      68             :                                     , UWord8 plc_fadeout_type                  
      69             :                                     )
      70             : {
      71             :     Counter i;
      72             :     Word16 lossDuration_dms, slow, fast, tmp16;
      73             :     Word16 plc_start_inFrames, plc_end_inFrames, plc_duration_inFrames, linFuncStartStop;
      74             :     Word16 randThreshold, ad_threshFac, energThreshold, s, s2, s3, mean_energy16;
      75             :     Word32 frame_energy, mean_nrg, fac;
      76             :     Word16 fflcAtten, cum_fading_slow_local, cum_fading_fast_local;
      77             : 
      78             : #ifdef DYNMEM_COUNT
      79             :     Dyn_Mem_In("processPLCDampingScrambling_fx", sizeof(struct {
      80             :         Counter i;
      81             :         Word16 lossDuration_dms, slow, fast, tmp16;
      82             :         Word16 plc_start_inFrames, plc_end_inFrames, plc_duration_inFrames, linFuncStartStop;
      83             :         Word16 randThreshold, ad_threshFac, energThreshold, s, s2, s3, mean_energy16;
      84             :         Word32 frame_energy, mean_nrg, fac;
      85             :         Word16 fflcAtten, cum_fading_slow_local, cum_fading_fast_local;
      86             :      }));
      87             : #endif
      88             : 
      89             :     /** preparation */
      90             : 
      91             :     /* get damping factors */
      92           0 :     tmp16 = mult(6554 /*0.2*/, stabFac);
      93           0 :     slow  = add(26214 /*0.8*/, tmp16);
      94           0 :     fast  = add( 9830 /*0.3*/, tmp16);
      95             : 
      96             : 
      97           0 :     SWITCH (frame_dms)
      98             :     {
      99           0 :     case 25:
     100           0 :         IF (sub(slow, 32767) < 0)
     101             :         {
     102           0 :             tmp16  = 0;
     103           0 :             slow = Sqrt16_lc3plus(slow, &tmp16);  move16();
     104           0 :             slow = shl(slow, tmp16);
     105             :         }
     106           0 :         IF (sub(slow, 32767) < 0)
     107             :         {
     108           0 :             tmp16  = 0;
     109           0 :             slow = Sqrt16_lc3plus(slow, &tmp16);  move16();
     110           0 :             slow = shl(slow, tmp16);
     111             :         }
     112           0 :         IF (sub(fast, 32767) < 0)
     113             :         {
     114           0 :             tmp16  = 0;
     115           0 :             fast = Sqrt16_lc3plus(fast, &tmp16);  move16();
     116           0 :             fast = shl(fast, tmp16);
     117             :         }
     118           0 :         IF (sub(fast, 32767) < 0)
     119             :         {
     120           0 :             tmp16  = 0;
     121           0 :             fast = Sqrt16_lc3plus(fast, &tmp16);  move16();
     122           0 :             fast = shl(fast, tmp16);
     123             :         }
     124           0 :         BREAK;
     125           0 :     case 50:
     126           0 :         IF (sub(slow, 32767) < 0)
     127             :         {
     128           0 :             tmp16  = 0;
     129           0 :             slow = Sqrt16_lc3plus(slow, &tmp16);  move16();
     130           0 :             slow = shl(slow, tmp16);
     131             :         }
     132           0 :         IF (sub(fast, 32767) < 0)
     133             :         {
     134           0 :             tmp16  = 0;
     135           0 :             fast = Sqrt16_lc3plus(fast, &tmp16);  move16();
     136           0 :             fast = shl(fast, tmp16);
     137             :         }
     138           0 :         BREAK;
     139           0 :     case 75:
     140           0 :         IF (sub(slow, 32767) < 0)
     141             :         {
     142           0 :             slow = mult(slow, mult(slow, slow));
     143             :         }
     144           0 :         IF (sub(slow, 32767) < 0)
     145             :         {
     146           0 :             tmp16  = 0;
     147           0 :             slow = Sqrt16_lc3plus(slow, &tmp16);  move16();
     148           0 :             slow = shl(slow, tmp16);
     149             :         }
     150           0 :         IF (sub(slow, 32767) < 0)
     151             :         {
     152           0 :             tmp16  = 0;
     153           0 :             slow = Sqrt16_lc3plus(slow, &tmp16);  move16();
     154           0 :             slow = shl(slow, tmp16);
     155             :         }
     156           0 :         IF (sub(fast, 32767) < 0)
     157             :         {
     158           0 :             fast = mult(fast, mult(fast, fast));
     159             :         }
     160           0 :         IF (sub(fast, 32767) < 0)
     161             :         {
     162           0 :             tmp16  = 0;
     163           0 :             fast = Sqrt16_lc3plus(fast, &tmp16);  move16();
     164           0 :             fast = shl(fast, tmp16);
     165             :         }
     166           0 :         IF (sub(fast, 32767) < 0)
     167             :         {
     168           0 :             tmp16  = 0;
     169           0 :             fast = Sqrt16_lc3plus(fast, &tmp16);  move16();
     170           0 :             fast = shl(fast, tmp16);
     171             :         }
     172           0 :         BREAK;
     173             :     }
     174             : 
     175           0 :     if (plc_fadeout_type == 0)
     176             :     {
     177           0 :         *cum_fading_slow = mult_r(*cum_fading_slow, slow);
     178           0 :         *cum_fading_fast = mult_r(*cum_fading_fast, fast);
     179             :     }
     180             : 
     181           0 :     IF ( sub(processDampScramb, 1) == 0 )
     182             :     {
     183           0 :         if (plc_fadeout_type != 0)
     184             :         {
     185           0 :             Word16 lost_frame_thr1 = 4;
     186           0 :             Word16 lost_frame_thr2 = 8;
     187             :             
     188           0 :             SWITCH (frame_dms)
     189             :             {
     190           0 :             case 25:
     191           0 :                 lost_frame_thr1 = 16;
     192           0 :                 lost_frame_thr2 = 32;
     193           0 :                 BREAK;
     194           0 :             case 50:
     195           0 :                 lost_frame_thr1 = 8;
     196           0 :                 lost_frame_thr2 = 16;
     197           0 :                 BREAK;
     198           0 :             case  75:
     199           0 :                 lost_frame_thr1 = 6;
     200           0 :                 lost_frame_thr2 = 11;
     201             :             }
     202           0 :             IF (sub(nbLostFramesInRow, lost_frame_thr1) < 0)
     203             :             {
     204           0 :                 cum_fading_slow_local = 32767; move16();
     205             :             }
     206           0 :             ELSE IF (sub(nbLostFramesInRow, lost_frame_thr2) < 0)
     207             :             {
     208           0 :                 cum_fading_slow_local = 29491; move16();
     209             :             }
     210             :             ELSE
     211             :             {
     212           0 :                 cum_fading_slow_local = 27852; move16();
     213             :             }
     214             :             
     215           0 :             *cum_fading_slow = mult_r(*cum_fading_slow, cum_fading_slow_local); move16();
     216           0 :             cum_fading_slow_local = *cum_fading_slow; move16();
     217             :         } else {
     218             :             /** rapid fading for FFLC */
     219           0 :             fflcAtten = 32767;  move16();
     220           0 :             cum_fading_slow_local = *cum_fading_slow;  move16();
     221           0 :             cum_fading_fast_local = *cum_fading_fast;  move16();
     222             : 
     223           0 :             IF (spec_inv_idx == 0)
     224             :             {
     225           0 :                 lossDuration_dms = DEPR_i_mult(nbLostFramesInRow, frame_dms);
     226           0 :                 IF (sub(lossDuration_dms, PLC_FADEOUT_IN_MS*10) > 0)
     227             :                 {
     228           0 :                     *cum_fflcAtten = 0;  move16();
     229           0 :                     fflcAtten = 0;  move16();
     230             :                 }
     231           0 :                 ELSE IF (sub(lossDuration_dms, 200) > 0)
     232             :                 {
     233           0 :                     SWITCH (frame_dms)
     234             :                     {
     235           0 :                     case  25: fflcAtten = PLC34_ATTEN_FAC_025_FX; BREAK;
     236           0 :                     case  50: fflcAtten = PLC34_ATTEN_FAC_050_FX; BREAK;
     237           0 :                     case  75: fflcAtten = PLC34_ATTEN_FAC_075_FX; BREAK;
     238           0 :                     case 100: fflcAtten = PLC34_ATTEN_FAC_100_FX; BREAK;
     239             :                     }
     240           0 :                 }
     241           0 :                 IF ( sub(fflcAtten, 32767) < 0 )
     242             :                 {
     243           0 :                     *cum_fflcAtten        = mult_r(*cum_fflcAtten, fflcAtten);
     244           0 :                     cum_fading_slow_local = mult_r(*cum_fading_slow, *cum_fflcAtten);
     245           0 :                     cum_fading_fast_local = mult_r(*cum_fading_fast, *cum_fflcAtten);
     246             :                 }
     247             :             }
     248             : 
     249             :             /** prepare fade-out function */
     250             :             /*  being 1 up to plc_start_inFrames, being 0 starting with
     251             :                 plc_end_inFrames; decreasing linearly in between */
     252           0 :             SWITCH (frame_dms)
     253             :             {
     254           0 :             case 25:
     255           0 :                 plc_start_inFrames = (10*PLC4_TRANSIT_START_IN_MS) /  25;  move16();
     256           0 :                 plc_end_inFrames   = (10*PLC4_TRANSIT_END_IN_MS)   /  25;  move16();
     257           0 :                 BREAK;
     258           0 :             case 50:
     259           0 :                 plc_start_inFrames = (10*PLC4_TRANSIT_START_IN_MS) /  50;  move16();
     260           0 :                 plc_end_inFrames   = (10*PLC4_TRANSIT_END_IN_MS)   /  50;  move16();
     261           0 :                 BREAK;
     262           0 :             case 75:
     263           0 :                 plc_start_inFrames = (10*PLC4_TRANSIT_START_IN_MS) /  75;  move16();
     264           0 :                 plc_end_inFrames   = (10*PLC4_TRANSIT_END_IN_MS)   /  75;  move16();
     265           0 :                 BREAK;
     266           0 :             default:
     267           0 :                 plc_start_inFrames = (10*PLC4_TRANSIT_START_IN_MS) / 100;  move16();
     268           0 :                 plc_end_inFrames   = (10*PLC4_TRANSIT_END_IN_MS)   / 100;  move16();
     269             :             }
     270             : 
     271           0 :             if (pitch_present == 0)
     272             :             {
     273           0 :                 plc_start_inFrames = 1;  move16();
     274             :             }
     275           0 :             plc_duration_inFrames = sub(plc_end_inFrames, plc_start_inFrames);
     276             : 
     277           0 :             IF (sub(nbLostFramesInRow, plc_start_inFrames) <= 0)
     278             :             {
     279           0 :                 linFuncStartStop = 32767;  move16();
     280             :             }
     281           0 :             ELSE IF (sub(nbLostFramesInRow, plc_end_inFrames) >= 0)
     282             :             {
     283           0 :                 linFuncStartStop =     0;  move16();
     284             :             }
     285             :             ELSE
     286             :             {
     287             :                 /*
     288             :                   x = xLostFramesInRow;
     289             :                   m = -1 / plc_duration_inFrames; 
     290             :                   b = -plc_end_inFrames; % shift on x axis
     291             :                   linFuncStartStop = m * (x + b);
     292             :                 */
     293           0 :                 linFuncStartStop = div_s(sub(plc_end_inFrames, nbLostFramesInRow), plc_duration_inFrames);
     294             :             }
     295             : 
     296             :             /** sign scrambling */
     297           0 :             randThreshold = mult(-32768, linFuncStartStop);
     298             :         }
     299             : 
     300           0 :         tmp16 = *seed;  move16();
     301           0 :         FOR (i = spec_inv_idx; i < L_spec; i++)
     302             :         {
     303           0 :             tmp16 = extract_l(L_mac0(16831, tmp16, 12821));
     304             : 
     305           0 :             IF (tmp16 < 0)
     306             :             {
     307           0 :                 test();
     308           0 :                 if (plc_fadeout_type != 0 || pitch_present == 0 || sub(tmp16, randThreshold) < 0 )
     309             :                 {
     310           0 :                     spec[i] = L_negate(spec[i]);
     311             :                 }
     312             :             }
     313             : 
     314             :         }
     315           0 :         *seed = tmp16; move16();
     316             : 
     317           0 :         if (plc_fadeout_type == 0)
     318             :         {
     319             :             /** adaptive damping */
     320           0 :             tmp16 = mult(18022 /* 10 - 1.2 */, linFuncStartStop);
     321           0 :             ad_threshFac = add(shr(tmp16, 1), 1228 /* 1.2 >> 1 */); /* exp = 5 */
     322             : 
     323           0 :             s = getScaleFactor32_lc3plus(&spec[spec_inv_idx], sub(L_spec, spec_inv_idx));
     324           0 :             frame_energy = 0;  move32();
     325           0 :             FOR (i = spec_inv_idx; i < L_spec; i++)
     326             :             {
     327           0 :                 tmp16     = extract_h(L_shl_sat(spec[i], sub(s, 4)));
     328           0 :                 frame_energy = L_mac0(frame_energy, tmp16, tmp16); /* exp = -(2*(s-16) - 8) */
     329             :             }
     330           0 :             mean_energy16 = BASOP_Util_Divide3216_Scale_lc3plus(frame_energy, sub(L_spec, spec_inv_idx), &s2);  /* exp = -(2*(s-16) - 8) + 16 - (15-s2) */
     331             : 
     332           0 :             energThreshold = mult(ad_threshFac, mean_energy16);    /* exp = -(2*(s-16) - 8) + 16 - (15-s2) + 5 */
     333             : 
     334           0 :             s3 = add(sub(29, shl(sub(s, 16), 1)), s2);
     335           0 :             IF (sub(energThreshold, 32767) < 0)
     336             :             {
     337           0 :                 energThreshold = Sqrt16_lc3plus(energThreshold, &s3);
     338             :             }
     339           0 :             s3 = sub(s3, 15);
     340             : 
     341           0 :             mean_nrg = L_shl_sat(L_deposit_l(energThreshold), s3); /* exp = 0 */
     342           0 :             fac = mult(sub(cum_fading_slow_local, cum_fading_fast_local), energThreshold);
     343           0 :             fac = L_shl_sat(L_deposit_l(fac), s3); /* exp = 0 */
     344             :         }
     345             :         
     346           0 :         FOR (i = spec_inv_idx; i < L_spec; i++)
     347             :         {
     348           0 :             if ( ( plc_fadeout_type != 0 )  ||  (L_sub(L_abs(spec[i]), mean_nrg) < 0) )
     349             :             {
     350           0 :                 spec[i] = Mpy_32_16_lc3plus(spec[i], cum_fading_slow_local);
     351             :             }
     352             :             else
     353             :             {
     354           0 :                 if (spec[i] > 0)
     355             :                 {
     356           0 :                     spec[i] = L_add_sat(Mpy_32_16_lc3plus(spec[i], cum_fading_fast_local), fac);
     357             :                 }
     358           0 :                 else if (spec[i] == 0)
     359             :                 {
     360           0 :                     spec[i] = Mpy_32_16_lc3plus(spec[i], cum_fading_fast_local);
     361             :                 }
     362             :                 else
     363             :                 {
     364           0 :                     spec[i] = L_sub_sat(Mpy_32_16_lc3plus(spec[i], cum_fading_fast_local), fac);
     365             :                 }
     366             :             }
     367             :         }
     368             :     }
     369             : 
     370             : #ifdef DYNMEM_COUNT
     371             :     Dyn_Mem_Out();
     372             : #endif
     373           0 : }
     374             : 
     375             : 

Generated by: LCOV version 1.14