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