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 "functions.h" 13 : 14 : 15 962751 : 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, LC3_FLOAT 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 962751 : LC3_FLOAT reg_val = 4.656612873077393e-10; 26 : 27 962751 : if (*old_targetBits < 0) { 28 12431 : *targetBitsOff = 0; 29 : } else { 30 950320 : tmp = MIN(40, MAX(-40, *targetBitsOff + *old_targetBits - old_specBits)); 31 950320 : *targetBitsOff = 0.8 * *targetBitsOff + 0.2 * tmp; 32 : } 33 : 34 962751 : *old_targetBits = nbitsSQ; 35 962751 : nbitsSQ = nbitsSQ + round(*targetBitsOff); 36 : 37 962751 : x_max = array_max_abs(x, lg); 38 : 39 962751 : if (hrmode && regBits > 0) 40 : { 41 0 : LC3_FLOAT M0 = 1e-5, M1 = 1e-5, rB_offset; 42 0 : LC3_FLOAT thresh = 2*frame_ms; 43 0 : for (i = 0; i < lg; i++) 44 : { 45 0 : M0 += fabs(x[i]); 46 0 : M1 += i*fabs(x[i]); 47 : } 48 : 49 0 : rB_offset = 8 * (1 - MIN(M1/M0, thresh) / thresh); 50 0 : reg_val = x_max * LC3_POW(2,-regBits - rB_offset); 51 : } 52 : 53 962751 : if (x_max < LC3_EPS) 54 : { 55 12931 : ind_min = quantizedGainOff; 56 12931 : ind = 0; 57 12931 : *old_targetBits = -1; 58 : } else { 59 949820 : if (hrmode == 1) { 60 0 : g_min = x_max / (32768 * 256 - 2); 61 : } else { 62 949820 : g_min = x_max / (32767 - 0.375); 63 : } 64 : /* Prevent positive rounding errors from LC3_LOG10 function */ 65 949820 : ind_min = 28.0 * LC3_LOGTEN(g_min); 66 : 67 949820 : ind_min = ceil(ind_min + LC3_FABS(ind_min) * LC3_EPS); 68 : 69 949820 : assert(LC3_POW(10, ind_min / 28.0) >= g_min); 70 949820 : assert(ind_min <= (255 + quantizedGainOff)); 71 : 72 949820 : N = lg; 73 : 74 949820 : j = 0; 75 50629620 : for (i = 0; i < N; i = i + 4) { 76 49679800 : tmp = x[i] * x[i]; 77 49679800 : tmp += x[i + 1] * x[i + 1]; 78 49679800 : tmp += x[i + 2] * x[i + 2]; 79 49679800 : tmp += x[i + 3] * x[i + 3]; 80 49679800 : en[j] = (28.0 / 20.0) * (7 + 10.0 * LC3_LOGTEN(tmp + reg_val)); 81 49679800 : j++; 82 : } 83 : 84 949820 : target = (28.0 / 20.0) * (1.4) * nbitsSQ; 85 949820 : fac = 256; 86 949820 : offset = 255 + quantizedGainOff; 87 : 88 8548380 : for (i = 0; i < 8; i++) 89 : { 90 7598560 : fac = fac >> 1; 91 7598560 : offset = offset - fac; 92 7598560 : ener = 0; 93 7598560 : iszero = 1; 94 : 95 405036960 : for (j = N / 4 - 1; j >= 0; j--) { 96 397438400 : tmp = en[j] - offset; 97 : 98 397438400 : if (tmp < (7.0) * (28.0 / 20.0)) { 99 36442195 : if (iszero == 0) { 100 25479779 : ener = ener + (2.7) * (28.0 / 20.0); 101 : } 102 : } else { 103 360996205 : if (tmp > (50.0) * (28.0 / 20.0)) { 104 73256287 : ener = ener + 2.0 * tmp - (50.0) * (28.0 / 20.0); 105 : } else { 106 287739918 : ener = ener + tmp; 107 : } 108 : 109 360996205 : iszero = 0; 110 : } 111 : } 112 : 113 7598560 : if (ener > target && iszero == 0) { 114 4084729 : offset = offset + fac; 115 : } 116 : } 117 : 118 949820 : if (offset < ind_min) { 119 72 : *old_targetBits = -1; 120 : } 121 : 122 949820 : ind = MAX(ind_min, offset) - quantizedGainOff; 123 : } 124 : 125 962751 : *quantizedGainMin = ind_min; 126 962751 : *quantizedGain = ind; 127 : 128 962751 : *gain = LC3_POW(10.0, ((ind + quantizedGainOff) / 28.0)); 129 962751 : }