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 : }
|