Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <assert.h>
38 : #include <stdint.h>
39 : #include "options.h"
40 : #include <math.h>
41 : #include "rom_com.h"
42 : #include "prot.h"
43 : #include "stat_dec.h"
44 : #include "wmc_auto.h"
45 :
46 : /*-------------------------------------------------------------------
47 : * Local constants
48 : *-------------------------------------------------------------------*/
49 :
50 : #define LOBUF_NO_SMOOTHING_MODE 1
51 :
52 : #define EPS ( 1e-12f )
53 : #define ENV_SCALE_OFFSET_1 90.309f /* 10*log10(2^30) */
54 : #define MAX_TEC_BW_LO ( 12 )
55 : #define MAX_NB_TEC_LOW_BAND ( 3 )
56 :
57 : const float TecSC[] = { 0.3662f, 0.1078f, 0.1194f, 0.1289f, 0.1365f, 0.1412f };
58 : const int16_t TecLowBandTable[] = { 0, 2, 4, 6 };
59 :
60 : #define TecSmoothingDeg 5
61 : #define NbTecLowBand 3
62 :
63 : #define ratioHiLoFac 1.5894f
64 : #define thRatio 0.3649f
65 : #define thRatio2 2.0288f
66 : #define thCorrCoef 0.8795f
67 : #define ratioHiLoFacDec ( 1.5894f * 0.75f )
68 :
69 : /*-------------------------------------------------------------------
70 : * calcLoBufferDec()
71 : *
72 : *
73 : *-------------------------------------------------------------------*/
74 :
75 19229 : static void calcLoBufferDec(
76 : float **pCldfbReal,
77 : float **pCldfbImag,
78 : float *loBuffer,
79 : const int16_t startPos,
80 : const int16_t stopPos,
81 : const int16_t bandOffsetBottom,
82 : const float scaleOffset )
83 : {
84 : int16_t slot, k, lb, li, ui;
85 : float nrg, tmp;
86 :
87 : /* calc loTempEnv */
88 326893 : for ( slot = startPos; slot < stopPos; slot++ )
89 : {
90 307664 : tmp = 0;
91 :
92 1230656 : for ( lb = 0; lb < NbTecLowBand; lb++ )
93 : {
94 922992 : li = TecLowBandTable[lb];
95 922992 : ui = TecLowBandTable[lb + 1];
96 :
97 922992 : nrg = 0;
98 2768976 : for ( k = li; k < ui; k++ )
99 : {
100 1845984 : nrg += pCldfbReal[slot][k + bandOffsetBottom] * pCldfbReal[slot][k + bandOffsetBottom] + pCldfbImag[slot][k + bandOffsetBottom] * pCldfbImag[slot][k + bandOffsetBottom];
101 : }
102 922992 : tmp += (float) log10( nrg * normReciprocal[ui - li] + EPS );
103 : }
104 :
105 307664 : loBuffer[slot] = 10.0f * tmp / NbTecLowBand + scaleOffset;
106 : }
107 :
108 19229 : return;
109 : }
110 :
111 :
112 : /*-------------------------------------------------------------------
113 : * calcLoBufferEnc()
114 : *
115 : *
116 : *-------------------------------------------------------------------*/
117 :
118 10310 : static void calcLoBufferEnc(
119 : float **pCldfbPow,
120 : const int16_t startPos,
121 : const int16_t stopPos,
122 : const int16_t bandOffsetBottom,
123 : const float scaleOffset,
124 : float *loBuffer )
125 : {
126 : int16_t slot, k, lb, li, ui;
127 : float nrg, tmp;
128 :
129 : /* calc loTempEnv */
130 175270 : for ( slot = startPos; slot < stopPos; slot++ )
131 : {
132 164960 : tmp = 0;
133 :
134 659840 : for ( lb = 0; lb < NbTecLowBand; lb++ )
135 : {
136 494880 : li = TecLowBandTable[lb];
137 494880 : ui = TecLowBandTable[lb + 1];
138 :
139 494880 : nrg = 0;
140 1484640 : for ( k = li; k < ui; k++ )
141 : {
142 989760 : nrg += pCldfbPow[slot][k + bandOffsetBottom];
143 : }
144 494880 : tmp += (float) log10( nrg * normReciprocal[ui - li] + EPS );
145 : }
146 :
147 164960 : loBuffer[slot] = 10.0f * tmp / NbTecLowBand + scaleOffset;
148 : }
149 :
150 10310 : return;
151 : }
152 :
153 :
154 : /*-------------------------------------------------------------------
155 : * calcLoTempEnv()
156 : *
157 : *
158 : *-------------------------------------------------------------------*/
159 :
160 15110 : static void calcLoTempEnv(
161 : const float *loBuffer,
162 : const int16_t noCols,
163 : float *loTempEnv,
164 : const float adjFac )
165 : {
166 : int16_t slot, i;
167 :
168 256870 : for ( slot = 0; slot < noCols; slot++ )
169 : {
170 241760 : loTempEnv[slot] = TecSC[0] * loBuffer[slot];
171 1450560 : for ( i = 1; i < TecSmoothingDeg + 1; i++ )
172 : {
173 1208800 : loTempEnv[slot] += TecSC[i] * loBuffer[slot - i];
174 : }
175 :
176 241760 : loTempEnv[slot] *= adjFac;
177 : }
178 :
179 15110 : return;
180 : }
181 :
182 : /*-------------------------------------------------------------------
183 : * calcHiTempEnv()
184 : *
185 : *
186 : *-------------------------------------------------------------------*/
187 :
188 10310 : static void calcHiTempEnv(
189 : float **pCldfbPow,
190 : const int16_t startPos,
191 : const int16_t stopPos,
192 : const int16_t lowSubband,
193 : const int16_t highSubband,
194 : const float scaleOffset,
195 : float *hiTempEnv )
196 : {
197 : int16_t timeIndex, k;
198 10310 : int16_t bwHigh = highSubband - lowSubband;
199 :
200 : /* set hiTempEnv */
201 175270 : for ( timeIndex = startPos; timeIndex < stopPos; timeIndex++ )
202 : {
203 164960 : hiTempEnv[timeIndex] = 0;
204 3464160 : for ( k = lowSubband; k < highSubband; k++ )
205 : {
206 3299200 : hiTempEnv[timeIndex] += pCldfbPow[timeIndex][k];
207 : }
208 164960 : hiTempEnv[timeIndex] = (float) ( 10 * log10( hiTempEnv[timeIndex] / bwHigh + EPS ) + scaleOffset );
209 : }
210 :
211 10310 : return;
212 : }
213 :
214 :
215 : /*-------------------------------------------------------------------
216 : * calcVar()
217 : *
218 : *
219 : *-------------------------------------------------------------------*/
220 :
221 44902 : static float calcVar(
222 : const float in[],
223 : const int16_t len,
224 : float *x )
225 : {
226 : float xx;
227 : int16_t i;
228 :
229 44902 : xx = 0;
230 44902 : *x = 0;
231 :
232 763334 : for ( i = 0; i < len; i++ )
233 : {
234 718432 : xx += in[i] * in[i];
235 718432 : *x += in[i];
236 : }
237 :
238 44902 : return ( xx - ( *x * *x ) / (float) len );
239 : }
240 :
241 :
242 : /*-------------------------------------------------------------------
243 : * calcCorrelationCoefficient2()
244 : *
245 : *
246 : *-------------------------------------------------------------------*/
247 :
248 14682 : static float calcCorrelationCoefficient2(
249 : const float in_vec1[],
250 : const float in_vec2[],
251 : const int16_t len,
252 : float var_x,
253 : float var_y,
254 : float x,
255 : float y )
256 : {
257 : int16_t i;
258 : float xy;
259 : float ans;
260 :
261 14682 : xy = 0;
262 :
263 249594 : for ( i = 0; i < len; i++ )
264 : {
265 234912 : xy += ( in_vec1[i] * in_vec2[i] );
266 : }
267 :
268 14682 : ans = ( xy - x * y / (float) ( len ) ) / (float) sqrt( var_x * var_y + EPS );
269 :
270 14682 : return ans;
271 : }
272 :
273 :
274 : /*-------------------------------------------------------------------
275 : * resetTecDec()
276 : *
277 : *
278 : *-------------------------------------------------------------------*/
279 :
280 1066 : void resetTecDec(
281 : TEC_DEC_HANDLE hTecDec )
282 : {
283 1066 : set_f( hTecDec->pGainTemp, 0, CLDFB_NO_COL_MAX );
284 :
285 1066 : set_f( hTecDec->loBuffer, 0.f, CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG );
286 :
287 1066 : return;
288 : }
289 :
290 :
291 : /*-------------------------------------------------------------------
292 : * calcLoTempEnv_TBE()
293 : *
294 : *
295 : *-------------------------------------------------------------------*/
296 :
297 30 : static void calcLoTempEnv_TBE(
298 : const float *loBuffer,
299 : const int16_t noCols,
300 : float *loTempEnv,
301 : const float adjFac )
302 : {
303 : int16_t slot, i;
304 30 : int16_t delay = 1;
305 :
306 510 : for ( slot = 0; slot < noCols; slot++ )
307 : {
308 480 : loTempEnv[slot] = TecSC[0] * loBuffer[slot - delay];
309 :
310 2880 : for ( i = 1; i < TecSmoothingDeg + 1; i++ )
311 : {
312 2400 : loTempEnv[slot] += TecSC[i] * loBuffer[slot - delay - i];
313 : }
314 :
315 480 : loTempEnv[slot] *= adjFac;
316 : }
317 :
318 30 : return;
319 : }
320 :
321 :
322 : /*-------------------------------------------------------------------
323 : * set_TEC_TFA_code()
324 : *
325 : *
326 : *-------------------------------------------------------------------*/
327 :
328 1518 : void set_TEC_TFA_code(
329 : const int16_t corrFlag,
330 : int16_t *tec_flag,
331 : int16_t *tfa_flag )
332 : {
333 1518 : *tec_flag = 0;
334 1518 : if ( *tfa_flag == 0 )
335 : {
336 1386 : if ( corrFlag == 1 )
337 : {
338 10 : *tec_flag = 1;
339 : }
340 1376 : else if ( corrFlag == 2 )
341 : {
342 20 : *tec_flag = 1;
343 20 : *tfa_flag = 1;
344 : }
345 : }
346 :
347 1518 : return;
348 : }
349 :
350 :
351 : /*-------------------------------------------------------------------
352 : * calcLoTempEnv_ns_TBE()
353 : *
354 : *
355 : *-------------------------------------------------------------------*/
356 :
357 48 : static void calcLoTempEnv_ns_TBE(
358 : const float *loBuffer,
359 : const int16_t noCols,
360 : float *loTempEnv )
361 : {
362 : int16_t slot;
363 48 : int16_t delay = 1;
364 48 : float fac = 1.4f;
365 :
366 816 : for ( slot = 0; slot < noCols; slot++ )
367 : {
368 768 : loTempEnv[slot] = fac * loBuffer[slot - delay];
369 : }
370 :
371 48 : return;
372 : }
373 :
374 :
375 : /*-------------------------------------------------------------------
376 : * calcLoTempEnv_ns()
377 : *
378 : *
379 : *-------------------------------------------------------------------*/
380 :
381 15110 : static void calcLoTempEnv_ns(
382 : const float *loBuffer,
383 : const int16_t noCols,
384 : float *loTempEnv )
385 : {
386 : int16_t slot;
387 :
388 256870 : for ( slot = 0; slot < noCols; slot++ )
389 : {
390 241760 : loTempEnv[slot] = loBuffer[slot];
391 : }
392 :
393 15110 : return;
394 : }
395 :
396 : /*-------------------------------------------------------------------
397 : * calcGainLinear_TBE()
398 : *
399 : *
400 : *-------------------------------------------------------------------*/
401 :
402 78 : static void calcGainLinear_TBE(
403 : const float *loTempEnv,
404 : const int16_t startPos,
405 : const int16_t stopPos,
406 : float *pGainTemp )
407 : {
408 : int16_t timeIndex;
409 : float ftmp;
410 :
411 1326 : for ( timeIndex = startPos; timeIndex < stopPos; timeIndex++ )
412 : {
413 1248 : ftmp = loTempEnv[timeIndex];
414 1248 : pGainTemp[timeIndex] = (float) pow( 10.0, 0.1 * ftmp );
415 : }
416 :
417 78 : return;
418 : }
419 :
420 :
421 : /*-------------------------------------------------------------------
422 : * calcGainTemp_TBE()
423 : *
424 : *
425 : *-------------------------------------------------------------------*/
426 :
427 19229 : void calcGainTemp_TBE(
428 : float **pCldfbRealSrc,
429 : float **pCldfbImagSrc,
430 : float *loBuffer,
431 : const int16_t startPos, /*!< Start position of the current envelope. */
432 : const int16_t stopPos, /*!< Stop position of the current envelope. */
433 : const int16_t lowSubband, /* lowSubband */
434 : float *pGainTemp,
435 : const int16_t code )
436 : {
437 : float loTempEnv[16];
438 19229 : const int16_t BW_LO = TecLowBandTable[NbTecLowBand];
439 : int16_t slot;
440 19229 : int16_t noCols = stopPos - startPos;
441 19229 : int16_t bandOffset = 0;
442 19229 : float scaleOffset = 0;
443 :
444 19229 : assert( lowSubband >= BW_LO );
445 :
446 19229 : bandOffset = lowSubband - BW_LO;
447 :
448 19229 : calcLoBufferDec( pCldfbRealSrc, pCldfbImagSrc, loBuffer + MAX_TEC_SMOOTHING_DEG, startPos, stopPos, bandOffset, scaleOffset );
449 :
450 19229 : if ( code > 0 )
451 : {
452 78 : if ( code != 2 )
453 : {
454 30 : calcLoTempEnv_TBE( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv, ratioHiLoFacDec );
455 : }
456 : else
457 : {
458 48 : calcLoTempEnv_ns_TBE( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv );
459 : }
460 :
461 78 : calcGainLinear_TBE( loTempEnv, startPos, stopPos, pGainTemp );
462 : }
463 :
464 :
465 134603 : for ( slot = 0; slot < MAX_TEC_SMOOTHING_DEG; slot++ )
466 : {
467 115374 : loBuffer[slot] = loBuffer[slot + stopPos];
468 : }
469 :
470 19229 : return;
471 : }
472 :
473 :
474 : /*-------------------------------------------------------------------
475 : * setSubfrConfig()
476 : *
477 : *
478 : *-------------------------------------------------------------------*/
479 :
480 460 : static void setSubfrConfig(
481 : const int16_t i_offset,
482 : int16_t *k_offset,
483 : int16_t *n_subfr,
484 : const int16_t l_subfr )
485 : {
486 460 : *n_subfr = N_TEC_TFA_SUBFR - i_offset;
487 460 : *k_offset = i_offset * l_subfr;
488 :
489 460 : return;
490 : }
491 :
492 :
493 : /*-------------------------------------------------------------------
494 : * calcSubfrNrg()
495 : *
496 : *
497 : *-------------------------------------------------------------------*/
498 :
499 460 : static float calcSubfrNrg(
500 : const float *hb_synth,
501 : const int16_t i_offset,
502 : float *enr,
503 : const int16_t k_offset,
504 : const int16_t l_subfr )
505 : {
506 : int16_t i, j, k;
507 460 : float enr_all = 1e-12f;
508 :
509 7796 : for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ )
510 : {
511 7336 : enr[i] = 1e-12f;
512 431336 : for ( j = 0; j < l_subfr; j++ )
513 : {
514 424000 : enr[i] += hb_synth[k] * hb_synth[k];
515 424000 : k++;
516 : }
517 7336 : enr_all += enr[i];
518 : }
519 :
520 460 : return enr_all;
521 : }
522 :
523 :
524 : /*-------------------------------------------------------------------
525 : * procTfa()
526 : *
527 : *
528 : *-------------------------------------------------------------------*/
529 :
530 382 : static void procTfa(
531 : float *hb_synth,
532 : const int16_t i_offset,
533 : const int16_t l_subfr )
534 : {
535 : int16_t i, j, k;
536 : int16_t k_offset, n_subfr;
537 : float enr[N_TEC_TFA_SUBFR], enr_ave;
538 :
539 382 : setSubfrConfig( i_offset, &k_offset, &n_subfr, l_subfr );
540 :
541 382 : enr_ave = calcSubfrNrg( hb_synth, i_offset, enr, k_offset, l_subfr ) / n_subfr;
542 :
543 6494 : for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ )
544 : {
545 : float gain;
546 :
547 6112 : gain = (float) sqrt( enr_ave / enr[i] );
548 :
549 363872 : for ( j = 0; j < l_subfr; j++ )
550 : {
551 357760 : hb_synth[k] *= gain;
552 357760 : k++;
553 : }
554 : }
555 :
556 382 : return;
557 : }
558 :
559 :
560 : /*-------------------------------------------------------------------
561 : * procTec()
562 : *
563 : *
564 : *-------------------------------------------------------------------*/
565 :
566 78 : static void procTec(
567 : float *hb_synth,
568 : const int16_t i_offset,
569 : const int16_t l_subfr,
570 : float *gain,
571 : const int16_t code )
572 : {
573 : int16_t i, j, k;
574 : int16_t k_offset, n_subfr;
575 : float enr[N_TEC_TFA_SUBFR], enr_ave, gain_ave;
576 : float inv_curr_enr[N_TEC_TFA_SUBFR];
577 : float max_inv_curr_enr, lower_limit_gain;
578 : float upper_limit_gain;
579 : float tmp;
580 :
581 78 : setSubfrConfig( i_offset, &k_offset, &n_subfr, l_subfr );
582 :
583 78 : enr_ave = calcSubfrNrg( hb_synth, i_offset, enr, k_offset, l_subfr ) / n_subfr;
584 :
585 78 : gain_ave = ( sum_f( &gain[i_offset], n_subfr ) + 1.0e-12f ) / n_subfr;
586 :
587 78 : max_inv_curr_enr = 10e-6f;
588 1302 : for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ )
589 : {
590 1224 : inv_curr_enr[i] = enr_ave / enr[i];
591 1224 : gain[i] /= gain_ave;
592 1224 : if ( max_inv_curr_enr < inv_curr_enr[i] )
593 : {
594 312 : max_inv_curr_enr = inv_curr_enr[i];
595 : }
596 : }
597 :
598 78 : lower_limit_gain = 0.1f;
599 78 : if ( lower_limit_gain > ( tmp = 1.f / max_inv_curr_enr ) )
600 : {
601 72 : lower_limit_gain = tmp * 0.5f;
602 : }
603 :
604 78 : upper_limit_gain = 1.2f;
605 78 : if ( code == LOBUF_NO_SMOOTHING_MODE )
606 : {
607 48 : upper_limit_gain = 3.0;
608 : }
609 :
610 1302 : for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ )
611 : {
612 1224 : if ( lower_limit_gain > gain[i] )
613 : {
614 30 : gain[i] = lower_limit_gain;
615 : }
616 1224 : gain[i] *= inv_curr_enr[i];
617 :
618 1224 : if ( gain[i] > upper_limit_gain )
619 : {
620 468 : gain[i] = upper_limit_gain;
621 : }
622 :
623 1224 : gain[i] = (float) sqrt( gain[i] );
624 67464 : for ( j = 0; j < l_subfr; j++ )
625 : {
626 66240 : hb_synth[k] *= gain[i];
627 66240 : k++;
628 : }
629 : }
630 :
631 78 : return;
632 : }
633 :
634 :
635 : /*-------------------------------------------------------------------
636 : * procTecTfa_TBE()
637 : *
638 : *
639 : *-------------------------------------------------------------------*/
640 :
641 460 : void procTecTfa_TBE(
642 : float *hb_synth,
643 : float *gain,
644 : const int16_t flat_flag,
645 : const int16_t last_core,
646 : const int16_t l_subfr,
647 : const int16_t code )
648 : {
649 460 : int16_t i_offset = 0;
650 :
651 460 : if ( flat_flag )
652 : {
653 382 : procTfa( hb_synth, i_offset, l_subfr );
654 : }
655 : else
656 : {
657 78 : if ( last_core != ACELP_CORE )
658 : {
659 24 : i_offset = 1;
660 : }
661 :
662 78 : procTec( hb_synth, i_offset, l_subfr, gain, code );
663 : }
664 :
665 460 : return;
666 : }
667 :
668 :
669 : /*-------------------------------------------------------------------
670 : * resetTecEnc()
671 : *
672 : *
673 : *-------------------------------------------------------------------*/
674 :
675 627 : void resetTecEnc(
676 : TEC_ENC_HANDLE hTecEnc,
677 : const int16_t flag )
678 : {
679 627 : if ( flag == 0 )
680 : {
681 389 : set_f( hTecEnc->loBuffer, 0.f, CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC );
682 389 : set_f( hTecEnc->hiTempEnv, 0.f, CLDFB_NO_COL_MAX + DELAY_TEMP_ENV_BUFF_TEC + EXT_DELAY_HI_TEMP_ENV );
683 389 : set_f( hTecEnc->loTempEnv, 0.f, CLDFB_NO_COL_MAX );
684 389 : set_f( hTecEnc->loTempEnv_ns, 0.f, CLDFB_NO_COL_MAX );
685 : }
686 : else
687 : {
688 238 : set_f( hTecEnc->loBuffer, 0.f, MAX_TEC_SMOOTHING_DEG );
689 : }
690 :
691 627 : return;
692 : }
693 :
694 :
695 : /*-------------------------------------------------------------------
696 : * calcHiEnvLoBuff()
697 : *
698 : *
699 : *-------------------------------------------------------------------*/
700 :
701 10310 : void calcHiEnvLoBuff(
702 : const int16_t noCols,
703 : const int16_t *pFreqBandTable, /*!< freqbandTable. */
704 : const int16_t nSfb, /*!< Number of scalefactors. */
705 : float **pCldfbPow,
706 : float *loBuffer,
707 : float *hiTempEnvOrig )
708 : {
709 10310 : const int16_t BW_LO = TecLowBandTable[NbTecLowBand];
710 10310 : const int16_t lowSubband = pFreqBandTable[0];
711 10310 : const int16_t highSubband = pFreqBandTable[nSfb];
712 :
713 10310 : int16_t bandOffsetBottom = lowSubband - BW_LO;
714 :
715 10310 : float scaleOffset = 0;
716 10310 : float *hiTempEnv = hiTempEnvOrig + EXT_DELAY_HI_TEMP_ENV;
717 :
718 10310 : assert( bandOffsetBottom > 0 );
719 :
720 : /* calc hiTempEnv*/
721 10310 : calcHiTempEnv( pCldfbPow, 0, noCols, lowSubband, highSubband, scaleOffset, hiTempEnv + DELAY_TEMP_ENV_BUFF_TEC );
722 :
723 : /* calc loBuffer */
724 10310 : calcLoBufferEnc( pCldfbPow, 0, noCols, bandOffsetBottom, scaleOffset, loBuffer + MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC );
725 :
726 10310 : return;
727 : }
728 :
729 :
730 : /*-------------------------------------------------------------------
731 : * calcLoEnvCheckCorrHiLo()
732 : *
733 : *
734 : *-------------------------------------------------------------------*/
735 :
736 15110 : void calcLoEnvCheckCorrHiLo(
737 : const int16_t noCols,
738 : const int16_t *pFreqBandTable, /*!< freqbandTable. */
739 : float *loBuffer,
740 : float *loTempEnv,
741 : float *loTempEnv_ns,
742 : float *hiTempEnvOrig,
743 : int16_t *corrFlag )
744 : {
745 15110 : const int16_t BW_LO = TecLowBandTable[NbTecLowBand];
746 15110 : const int16_t lowSubband = pFreqBandTable[0];
747 : int16_t i;
748 : float corrCoef;
749 15110 : int16_t bandOffsetBottom = lowSubband - BW_LO;
750 : float ratio;
751 : float hiVar, loVar;
752 : float hiSum, loSum;
753 15110 : int16_t code = 0; /* SET TENTATIVELY */
754 : float loVar_ns;
755 : float loSum_ns;
756 : float diff_hi_lo_sum;
757 :
758 15110 : float *hiTempEnv = hiTempEnvOrig + EXT_DELAY_HI_TEMP_ENV;
759 :
760 15110 : assert( bandOffsetBottom > 0 );
761 :
762 15110 : hiVar = calcVar( hiTempEnv, noCols, &hiSum );
763 :
764 : /* calc loTempEnv */
765 15110 : calcLoTempEnv( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv, ratioHiLoFac );
766 :
767 15110 : calcLoTempEnv_ns( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv_ns );
768 :
769 15110 : loVar_ns = calcVar( loTempEnv_ns, noCols, &loSum_ns );
770 15110 : diff_hi_lo_sum = loSum_ns - hiSum;
771 :
772 15110 : if ( hiVar > 800 && loVar_ns > 720 && diff_hi_lo_sum < 100 )
773 : {
774 428 : code = 1;
775 : }
776 :
777 15110 : *corrFlag = 0;
778 :
779 15110 : assert( code == 0 || code == 1 );
780 :
781 15110 : if ( code )
782 : {
783 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
784 : /* ++++ code == 1 +++++*/
785 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
786 : int16_t maxPosHi, maxPosLo;
787 : float maxHi, maxLo;
788 :
789 428 : maxHi = hiTempEnv[0];
790 428 : maxLo = loTempEnv_ns[0];
791 428 : maxPosHi = maxPosLo = 0;
792 :
793 6848 : for ( i = 1; i < noCols; i++ )
794 : {
795 6420 : if ( maxHi < hiTempEnv[i] )
796 : {
797 2000 : maxHi = hiTempEnv[i];
798 2000 : maxPosHi = i;
799 : }
800 :
801 6420 : if ( maxLo < loTempEnv_ns[i] )
802 : {
803 1637 : maxLo = loTempEnv_ns[i];
804 1637 : maxPosLo = i;
805 : }
806 : }
807 :
808 428 : if ( abs( maxPosHi - maxPosLo ) < 2 )
809 : {
810 321 : *corrFlag = 2;
811 : }
812 :
813 : {
814 428 : float feature_max = 0;
815 428 : int16_t pos_feature_max = 0;
816 : float feature[16];
817 :
818 : float min_local, max_local;
819 : int16_t j;
820 428 : int16_t len_window = EXT_DELAY_HI_TEMP_ENV + 1;
821 428 : float *curr_pos = hiTempEnv;
822 :
823 428 : feature_max = 0;
824 428 : pos_feature_max = 0;
825 :
826 7276 : for ( i = 0; i < 16; i++, curr_pos++ )
827 : {
828 6848 : max_local = min_local = curr_pos[0];
829 :
830 20544 : for ( j = 1; j < len_window; j++ )
831 : {
832 13696 : if ( max_local < curr_pos[-j] )
833 : {
834 3684 : max_local = curr_pos[-j];
835 : }
836 :
837 13696 : if ( min_local > curr_pos[-j] )
838 : {
839 5615 : min_local = curr_pos[-j];
840 : }
841 : }
842 :
843 6848 : feature[i] = max_local - min_local;
844 :
845 6848 : if ( feature_max < feature[i] )
846 : {
847 1178 : feature_max = feature[i];
848 1178 : pos_feature_max = i;
849 : }
850 : }
851 :
852 428 : if ( *corrFlag > 0 )
853 : {
854 321 : if ( !( feature_max > 20 && abs( pos_feature_max - maxPosHi ) < 3 ) )
855 : {
856 138 : *corrFlag = 0;
857 : }
858 : }
859 : }
860 : }
861 : else
862 : {
863 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
864 : /* ++++ code == 0 ++++*/
865 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
866 :
867 : /* calc the variance of loTempEnv */
868 14682 : loVar = calcVar( loTempEnv, noCols, &loSum );
869 :
870 : /* calc correlation coefficient between loTempEnv and hiTempEnv */
871 14682 : corrCoef = calcCorrelationCoefficient2( hiTempEnv, loTempEnv, noCols, hiVar, loVar, hiSum, loSum );
872 :
873 14682 : ratio = hiVar / ( loVar + EPS );
874 :
875 14682 : if ( corrCoef >= thCorrCoef && ratio > thRatio && ratio < thRatio2 )
876 : {
877 321 : *corrFlag = 1;
878 : }
879 : }
880 :
881 241760 : for ( i = 0; i < MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC; i++ )
882 : {
883 226650 : loBuffer[i] = loBuffer[noCols + i];
884 : }
885 :
886 181320 : for ( i = 0; i < DELAY_TEMP_ENV_BUFF_TEC + EXT_DELAY_HI_TEMP_ENV; i++ )
887 : {
888 166210 : hiTempEnvOrig[i] = hiTempEnvOrig[noCols + i];
889 : }
890 :
891 15110 : return;
892 : }
893 :
894 :
895 : /*-------------------------------------------------------------------
896 : * tecEnc_TBE()
897 : *
898 : *
899 : *-------------------------------------------------------------------*/
900 :
901 1518 : void tecEnc_TBE(
902 : int16_t *corrFlag,
903 : const float *voicing,
904 : const int16_t coder_type )
905 : {
906 : float voice_sum;
907 : float voice_diff;
908 :
909 : /*-----------------------------------------------------------------*
910 : * TEC updates
911 : *-----------------------------------------------------------------*/
912 :
913 1518 : voice_sum = voicing[0] + voicing[1];
914 1518 : voice_diff = voicing[0] - voicing[1];
915 :
916 1518 : if ( voice_diff < 0 )
917 : {
918 760 : voice_diff *= -1.0f;
919 : }
920 :
921 1518 : if ( *corrFlag == 1 )
922 : {
923 54 : if ( coder_type == INACTIVE || ( ( voice_sum > 0.35 * 2 && voice_sum < 0.55 * 2 ) && ( voice_diff < 0.2 ) ) )
924 : {
925 4 : *corrFlag = 0;
926 : }
927 : }
928 1518 : if ( voice_sum > 0.6 * 2 )
929 : {
930 1288 : *corrFlag = 0;
931 : }
932 :
933 1518 : return;
934 : }
|