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 3750 : 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 63750 : for ( slot = startPos; slot < stopPos; slot++ )
89 : {
90 60000 : tmp = 0;
91 :
92 240000 : for ( lb = 0; lb < NbTecLowBand; lb++ )
93 : {
94 180000 : li = TecLowBandTable[lb];
95 180000 : ui = TecLowBandTable[lb + 1];
96 :
97 180000 : nrg = 0;
98 540000 : for ( k = li; k < ui; k++ )
99 : {
100 360000 : nrg += pCldfbReal[slot][k + bandOffsetBottom] * pCldfbReal[slot][k + bandOffsetBottom] + pCldfbImag[slot][k + bandOffsetBottom] * pCldfbImag[slot][k + bandOffsetBottom];
101 : }
102 180000 : tmp += (float) log10( nrg * normReciprocal[ui - li] + EPS );
103 : }
104 :
105 60000 : loBuffer[slot] = 10.0f * tmp / NbTecLowBand + scaleOffset;
106 : }
107 :
108 3750 : return;
109 : }
110 :
111 :
112 : /*-------------------------------------------------------------------
113 : * calcLoBufferEnc()
114 : *
115 : *
116 : *-------------------------------------------------------------------*/
117 :
118 3100 : 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 52700 : for ( slot = startPos; slot < stopPos; slot++ )
131 : {
132 49600 : tmp = 0;
133 :
134 198400 : for ( lb = 0; lb < NbTecLowBand; lb++ )
135 : {
136 148800 : li = TecLowBandTable[lb];
137 148800 : ui = TecLowBandTable[lb + 1];
138 :
139 148800 : nrg = 0;
140 446400 : for ( k = li; k < ui; k++ )
141 : {
142 297600 : nrg += pCldfbPow[slot][k + bandOffsetBottom];
143 : }
144 148800 : tmp += (float) log10( nrg * normReciprocal[ui - li] + EPS );
145 : }
146 :
147 49600 : loBuffer[slot] = 10.0f * tmp / NbTecLowBand + scaleOffset;
148 : }
149 :
150 3100 : return;
151 : }
152 :
153 :
154 : /*-------------------------------------------------------------------
155 : * calcLoTempEnv()
156 : *
157 : *
158 : *-------------------------------------------------------------------*/
159 :
160 3100 : 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 52700 : for ( slot = 0; slot < noCols; slot++ )
169 : {
170 49600 : loTempEnv[slot] = TecSC[0] * loBuffer[slot];
171 297600 : for ( i = 1; i < TecSmoothingDeg + 1; i++ )
172 : {
173 248000 : loTempEnv[slot] += TecSC[i] * loBuffer[slot - i];
174 : }
175 :
176 49600 : loTempEnv[slot] *= adjFac;
177 : }
178 :
179 3100 : return;
180 : }
181 :
182 : /*-------------------------------------------------------------------
183 : * calcHiTempEnv()
184 : *
185 : *
186 : *-------------------------------------------------------------------*/
187 :
188 3100 : 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 3100 : int16_t bwHigh = highSubband - lowSubband;
199 :
200 : /* set hiTempEnv */
201 52700 : for ( timeIndex = startPos; timeIndex < stopPos; timeIndex++ )
202 : {
203 49600 : hiTempEnv[timeIndex] = 0;
204 1041600 : for ( k = lowSubband; k < highSubband; k++ )
205 : {
206 992000 : hiTempEnv[timeIndex] += pCldfbPow[timeIndex][k];
207 : }
208 49600 : hiTempEnv[timeIndex] = (float) ( 10 * log10( hiTempEnv[timeIndex] / bwHigh + EPS ) + scaleOffset );
209 : }
210 :
211 3100 : return;
212 : }
213 :
214 :
215 : /*-------------------------------------------------------------------
216 : * calcVar()
217 : *
218 : *
219 : *-------------------------------------------------------------------*/
220 :
221 9185 : 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 9185 : xx = 0;
230 9185 : *x = 0;
231 :
232 156145 : for ( i = 0; i < len; i++ )
233 : {
234 146960 : xx += in[i] * in[i];
235 146960 : *x += in[i];
236 : }
237 :
238 9185 : return ( xx - ( *x * *x ) / (float) len );
239 : }
240 :
241 :
242 : /*-------------------------------------------------------------------
243 : * calcCorrelationCoefficient2()
244 : *
245 : *
246 : *-------------------------------------------------------------------*/
247 :
248 2985 : 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 2985 : xy = 0;
262 :
263 50745 : for ( i = 0; i < len; i++ )
264 : {
265 47760 : xy += ( in_vec1[i] * in_vec2[i] );
266 : }
267 :
268 2985 : ans = ( xy - x * y / (float) ( len ) ) / (float) sqrt( var_x * var_y + EPS );
269 :
270 2985 : return ans;
271 : }
272 :
273 :
274 : /*-------------------------------------------------------------------
275 : * resetTecDec()
276 : *
277 : *
278 : *-------------------------------------------------------------------*/
279 :
280 123 : void resetTecDec(
281 : TEC_DEC_HANDLE hTecDec )
282 : {
283 123 : set_f( hTecDec->pGainTemp, 0, CLDFB_NO_COL_MAX );
284 :
285 123 : set_f( hTecDec->loBuffer, 0.f, CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG );
286 :
287 123 : return;
288 : }
289 :
290 :
291 : /*-------------------------------------------------------------------
292 : * calcLoTempEnv_TBE()
293 : *
294 : *
295 : *-------------------------------------------------------------------*/
296 :
297 15 : 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 15 : int16_t delay = 1;
305 :
306 255 : for ( slot = 0; slot < noCols; slot++ )
307 : {
308 240 : loTempEnv[slot] = TecSC[0] * loBuffer[slot - delay];
309 :
310 1440 : for ( i = 1; i < TecSmoothingDeg + 1; i++ )
311 : {
312 1200 : loTempEnv[slot] += TecSC[i] * loBuffer[slot - delay - i];
313 : }
314 :
315 240 : loTempEnv[slot] *= adjFac;
316 : }
317 :
318 15 : return;
319 : }
320 :
321 :
322 : /*-------------------------------------------------------------------
323 : * set_TEC_TFA_code()
324 : *
325 : *
326 : *-------------------------------------------------------------------*/
327 :
328 604 : void set_TEC_TFA_code(
329 : const int16_t corrFlag,
330 : int16_t *tec_flag,
331 : int16_t *tfa_flag )
332 : {
333 604 : *tec_flag = 0;
334 604 : if ( *tfa_flag == 0 )
335 : {
336 545 : if ( corrFlag == 1 )
337 : {
338 5 : *tec_flag = 1;
339 : }
340 540 : else if ( corrFlag == 2 )
341 : {
342 4 : *tec_flag = 1;
343 4 : *tfa_flag = 1;
344 : }
345 : }
346 :
347 604 : return;
348 : }
349 :
350 :
351 : /*-------------------------------------------------------------------
352 : * calcLoTempEnv_ns_TBE()
353 : *
354 : *
355 : *-------------------------------------------------------------------*/
356 :
357 12 : static void calcLoTempEnv_ns_TBE(
358 : const float *loBuffer,
359 : const int16_t noCols,
360 : float *loTempEnv )
361 : {
362 : int16_t slot;
363 12 : int16_t delay = 1;
364 12 : float fac = 1.4f;
365 :
366 204 : for ( slot = 0; slot < noCols; slot++ )
367 : {
368 192 : loTempEnv[slot] = fac * loBuffer[slot - delay];
369 : }
370 :
371 12 : return;
372 : }
373 :
374 :
375 : /*-------------------------------------------------------------------
376 : * calcLoTempEnv_ns()
377 : *
378 : *
379 : *-------------------------------------------------------------------*/
380 :
381 3100 : static void calcLoTempEnv_ns(
382 : const float *loBuffer,
383 : const int16_t noCols,
384 : float *loTempEnv )
385 : {
386 : int16_t slot;
387 :
388 52700 : for ( slot = 0; slot < noCols; slot++ )
389 : {
390 49600 : loTempEnv[slot] = loBuffer[slot];
391 : }
392 :
393 3100 : return;
394 : }
395 :
396 : /*-------------------------------------------------------------------
397 : * calcGainLinear_TBE()
398 : *
399 : *
400 : *-------------------------------------------------------------------*/
401 :
402 27 : 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 459 : for ( timeIndex = startPos; timeIndex < stopPos; timeIndex++ )
412 : {
413 432 : ftmp = loTempEnv[timeIndex];
414 432 : pGainTemp[timeIndex] = (float) pow( 10.0, 0.1 * ftmp );
415 : }
416 :
417 27 : return;
418 : }
419 :
420 :
421 : /*-------------------------------------------------------------------
422 : * calcGainTemp_TBE()
423 : *
424 : *
425 : *-------------------------------------------------------------------*/
426 :
427 3750 : 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 3750 : const int16_t BW_LO = TecLowBandTable[NbTecLowBand];
439 : int16_t slot;
440 3750 : int16_t noCols = stopPos - startPos;
441 3750 : int16_t bandOffset = 0;
442 3750 : float scaleOffset = 0;
443 :
444 3750 : assert( lowSubband >= BW_LO );
445 :
446 3750 : bandOffset = lowSubband - BW_LO;
447 :
448 3750 : calcLoBufferDec( pCldfbRealSrc, pCldfbImagSrc, loBuffer + MAX_TEC_SMOOTHING_DEG, startPos, stopPos, bandOffset, scaleOffset );
449 :
450 3750 : if ( code > 0 )
451 : {
452 27 : if ( code != 2 )
453 : {
454 15 : calcLoTempEnv_TBE( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv, ratioHiLoFacDec );
455 : }
456 : else
457 : {
458 12 : calcLoTempEnv_ns_TBE( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv );
459 : }
460 :
461 27 : calcGainLinear_TBE( loTempEnv, startPos, stopPos, pGainTemp );
462 : }
463 :
464 :
465 26250 : for ( slot = 0; slot < MAX_TEC_SMOOTHING_DEG; slot++ )
466 : {
467 22500 : loBuffer[slot] = loBuffer[slot + stopPos];
468 : }
469 :
470 3750 : return;
471 : }
472 :
473 :
474 : /*-------------------------------------------------------------------
475 : * setSubfrConfig()
476 : *
477 : *
478 : *-------------------------------------------------------------------*/
479 :
480 204 : 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 204 : *n_subfr = N_TEC_TFA_SUBFR - i_offset;
487 204 : *k_offset = i_offset * l_subfr;
488 :
489 204 : return;
490 : }
491 :
492 :
493 : /*-------------------------------------------------------------------
494 : * calcSubfrNrg()
495 : *
496 : *
497 : *-------------------------------------------------------------------*/
498 :
499 204 : 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 204 : float enr_all = 1e-12f;
508 :
509 3468 : for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ )
510 : {
511 3264 : enr[i] = 1e-12f;
512 199104 : for ( j = 0; j < l_subfr; j++ )
513 : {
514 195840 : enr[i] += hb_synth[k] * hb_synth[k];
515 195840 : k++;
516 : }
517 3264 : enr_all += enr[i];
518 : }
519 :
520 204 : return enr_all;
521 : }
522 :
523 :
524 : /*-------------------------------------------------------------------
525 : * procTfa()
526 : *
527 : *
528 : *-------------------------------------------------------------------*/
529 :
530 177 : 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 177 : setSubfrConfig( i_offset, &k_offset, &n_subfr, l_subfr );
540 :
541 177 : enr_ave = calcSubfrNrg( hb_synth, i_offset, enr, k_offset, l_subfr ) / n_subfr;
542 :
543 3009 : for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ )
544 : {
545 : float gain;
546 :
547 2832 : gain = (float) sqrt( enr_ave / enr[i] );
548 :
549 172752 : for ( j = 0; j < l_subfr; j++ )
550 : {
551 169920 : hb_synth[k] *= gain;
552 169920 : k++;
553 : }
554 : }
555 :
556 177 : return;
557 : }
558 :
559 :
560 : /*-------------------------------------------------------------------
561 : * procTec()
562 : *
563 : *
564 : *-------------------------------------------------------------------*/
565 :
566 27 : 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 27 : setSubfrConfig( i_offset, &k_offset, &n_subfr, l_subfr );
582 :
583 27 : enr_ave = calcSubfrNrg( hb_synth, i_offset, enr, k_offset, l_subfr ) / n_subfr;
584 :
585 27 : gain_ave = ( sum_f( &gain[i_offset], n_subfr ) + 1.0e-12f ) / n_subfr;
586 :
587 27 : max_inv_curr_enr = 10e-6f;
588 459 : for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ )
589 : {
590 432 : inv_curr_enr[i] = enr_ave / enr[i];
591 432 : gain[i] /= gain_ave;
592 432 : if ( max_inv_curr_enr < inv_curr_enr[i] )
593 : {
594 120 : max_inv_curr_enr = inv_curr_enr[i];
595 : }
596 : }
597 :
598 27 : lower_limit_gain = 0.1f;
599 27 : if ( lower_limit_gain > ( tmp = 1.f / max_inv_curr_enr ) )
600 : {
601 24 : lower_limit_gain = tmp * 0.5f;
602 : }
603 :
604 27 : upper_limit_gain = 1.2f;
605 27 : if ( code == LOBUF_NO_SMOOTHING_MODE )
606 : {
607 12 : upper_limit_gain = 3.0;
608 : }
609 :
610 459 : for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ )
611 : {
612 432 : if ( lower_limit_gain > gain[i] )
613 : {
614 15 : gain[i] = lower_limit_gain;
615 : }
616 432 : gain[i] *= inv_curr_enr[i];
617 :
618 432 : if ( gain[i] > upper_limit_gain )
619 : {
620 138 : gain[i] = upper_limit_gain;
621 : }
622 :
623 432 : gain[i] = (float) sqrt( gain[i] );
624 26352 : for ( j = 0; j < l_subfr; j++ )
625 : {
626 25920 : hb_synth[k] *= gain[i];
627 25920 : k++;
628 : }
629 : }
630 :
631 27 : return;
632 : }
633 :
634 :
635 : /*-------------------------------------------------------------------
636 : * procTecTfa_TBE()
637 : *
638 : *
639 : *-------------------------------------------------------------------*/
640 :
641 204 : 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 204 : int16_t i_offset = 0;
650 :
651 204 : if ( flat_flag )
652 : {
653 177 : procTfa( hb_synth, i_offset, l_subfr );
654 : }
655 : else
656 : {
657 27 : if ( last_core != ACELP_CORE )
658 : {
659 0 : i_offset = 1;
660 : }
661 :
662 27 : procTec( hb_synth, i_offset, l_subfr, gain, code );
663 : }
664 :
665 204 : return;
666 : }
667 :
668 :
669 : /*-------------------------------------------------------------------
670 : * resetTecEnc()
671 : *
672 : *
673 : *-------------------------------------------------------------------*/
674 :
675 101 : void resetTecEnc(
676 : TEC_ENC_HANDLE hTecEnc,
677 : const int16_t flag )
678 : {
679 101 : if ( flag == 0 )
680 : {
681 27 : set_f( hTecEnc->loBuffer, 0.f, CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC );
682 27 : set_f( hTecEnc->hiTempEnv, 0.f, CLDFB_NO_COL_MAX + DELAY_TEMP_ENV_BUFF_TEC + EXT_DELAY_HI_TEMP_ENV );
683 27 : set_f( hTecEnc->loTempEnv, 0.f, CLDFB_NO_COL_MAX );
684 27 : set_f( hTecEnc->loTempEnv_ns, 0.f, CLDFB_NO_COL_MAX );
685 : }
686 : else
687 : {
688 74 : set_f( hTecEnc->loBuffer, 0.f, MAX_TEC_SMOOTHING_DEG );
689 : }
690 :
691 101 : return;
692 : }
693 :
694 :
695 : /*-------------------------------------------------------------------
696 : * calcHiEnvLoBuff()
697 : *
698 : *
699 : *-------------------------------------------------------------------*/
700 :
701 3100 : 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 3100 : const int16_t BW_LO = TecLowBandTable[NbTecLowBand];
710 3100 : const int16_t lowSubband = pFreqBandTable[0];
711 3100 : const int16_t highSubband = pFreqBandTable[nSfb];
712 :
713 3100 : int16_t bandOffsetBottom = lowSubband - BW_LO;
714 :
715 3100 : float scaleOffset = 0;
716 3100 : float *hiTempEnv = hiTempEnvOrig + EXT_DELAY_HI_TEMP_ENV;
717 :
718 3100 : assert( bandOffsetBottom > 0 );
719 :
720 : /* calc hiTempEnv*/
721 3100 : calcHiTempEnv( pCldfbPow, 0, noCols, lowSubband, highSubband, scaleOffset, hiTempEnv + DELAY_TEMP_ENV_BUFF_TEC );
722 :
723 : /* calc loBuffer */
724 3100 : calcLoBufferEnc( pCldfbPow, 0, noCols, bandOffsetBottom, scaleOffset, loBuffer + MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC );
725 :
726 3100 : return;
727 : }
728 :
729 :
730 : /*-------------------------------------------------------------------
731 : * calcLoEnvCheckCorrHiLo()
732 : *
733 : *
734 : *-------------------------------------------------------------------*/
735 :
736 3100 : 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 3100 : const int16_t BW_LO = TecLowBandTable[NbTecLowBand];
746 3100 : const int16_t lowSubband = pFreqBandTable[0];
747 : int16_t i;
748 : float corrCoef;
749 3100 : int16_t bandOffsetBottom = lowSubband - BW_LO;
750 : float ratio;
751 : float hiVar, loVar;
752 : float hiSum, loSum;
753 3100 : int16_t code = 0; /* SET TENTATIVELY */
754 : float loVar_ns;
755 : float loSum_ns;
756 : float diff_hi_lo_sum;
757 :
758 3100 : float *hiTempEnv = hiTempEnvOrig + EXT_DELAY_HI_TEMP_ENV;
759 :
760 3100 : assert( bandOffsetBottom > 0 );
761 :
762 3100 : hiVar = calcVar( hiTempEnv, noCols, &hiSum );
763 :
764 : /* calc loTempEnv */
765 3100 : calcLoTempEnv( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv, ratioHiLoFac );
766 :
767 3100 : calcLoTempEnv_ns( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv_ns );
768 :
769 3100 : loVar_ns = calcVar( loTempEnv_ns, noCols, &loSum_ns );
770 3100 : diff_hi_lo_sum = loSum_ns - hiSum;
771 :
772 3100 : if ( hiVar > 800 && loVar_ns > 720 && diff_hi_lo_sum < 100 )
773 : {
774 115 : code = 1;
775 : }
776 :
777 3100 : *corrFlag = 0;
778 :
779 3100 : assert( code == 0 || code == 1 );
780 :
781 3100 : if ( code )
782 : {
783 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
784 : /* ++++ code == 1 +++++*/
785 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
786 : int16_t maxPosHi, maxPosLo;
787 : float maxHi, maxLo;
788 :
789 115 : maxHi = hiTempEnv[0];
790 115 : maxLo = loTempEnv_ns[0];
791 115 : maxPosHi = maxPosLo = 0;
792 :
793 1840 : for ( i = 1; i < noCols; i++ )
794 : {
795 1725 : if ( maxHi < hiTempEnv[i] )
796 : {
797 463 : maxHi = hiTempEnv[i];
798 463 : maxPosHi = i;
799 : }
800 :
801 1725 : if ( maxLo < loTempEnv_ns[i] )
802 : {
803 478 : maxLo = loTempEnv_ns[i];
804 478 : maxPosLo = i;
805 : }
806 : }
807 :
808 115 : if ( abs( maxPosHi - maxPosLo ) < 2 )
809 : {
810 90 : *corrFlag = 2;
811 : }
812 :
813 : {
814 115 : float feature_max = 0;
815 115 : int16_t pos_feature_max = 0;
816 : float feature[16];
817 :
818 : float min_local, max_local;
819 : int16_t j;
820 115 : int16_t len_window = EXT_DELAY_HI_TEMP_ENV + 1;
821 115 : float *curr_pos = hiTempEnv;
822 :
823 115 : feature_max = 0;
824 115 : pos_feature_max = 0;
825 :
826 1955 : for ( i = 0; i < 16; i++, curr_pos++ )
827 : {
828 1840 : max_local = min_local = curr_pos[0];
829 :
830 5520 : for ( j = 1; j < len_window; j++ )
831 : {
832 3680 : if ( max_local < curr_pos[-j] )
833 : {
834 1333 : max_local = curr_pos[-j];
835 : }
836 :
837 3680 : if ( min_local > curr_pos[-j] )
838 : {
839 1458 : min_local = curr_pos[-j];
840 : }
841 : }
842 :
843 1840 : feature[i] = max_local - min_local;
844 :
845 1840 : if ( feature_max < feature[i] )
846 : {
847 371 : feature_max = feature[i];
848 371 : pos_feature_max = i;
849 : }
850 : }
851 :
852 115 : if ( *corrFlag > 0 )
853 : {
854 90 : if ( !( feature_max > 20 && abs( pos_feature_max - maxPosHi ) < 3 ) )
855 : {
856 44 : *corrFlag = 0;
857 : }
858 : }
859 : }
860 : }
861 : else
862 : {
863 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
864 : /* ++++ code == 0 ++++*/
865 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
866 :
867 : /* calc the variance of loTempEnv */
868 2985 : loVar = calcVar( loTempEnv, noCols, &loSum );
869 :
870 : /* calc correlation coefficient between loTempEnv and hiTempEnv */
871 2985 : corrCoef = calcCorrelationCoefficient2( hiTempEnv, loTempEnv, noCols, hiVar, loVar, hiSum, loSum );
872 :
873 2985 : ratio = hiVar / ( loVar + EPS );
874 :
875 2985 : if ( corrCoef >= thCorrCoef && ratio > thRatio && ratio < thRatio2 )
876 : {
877 99 : *corrFlag = 1;
878 : }
879 : }
880 :
881 49600 : for ( i = 0; i < MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC; i++ )
882 : {
883 46500 : loBuffer[i] = loBuffer[noCols + i];
884 : }
885 :
886 37200 : for ( i = 0; i < DELAY_TEMP_ENV_BUFF_TEC + EXT_DELAY_HI_TEMP_ENV; i++ )
887 : {
888 34100 : hiTempEnvOrig[i] = hiTempEnvOrig[noCols + i];
889 : }
890 :
891 3100 : return;
892 : }
893 :
894 :
895 : /*-------------------------------------------------------------------
896 : * tecEnc_TBE()
897 : *
898 : *
899 : *-------------------------------------------------------------------*/
900 :
901 604 : 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 604 : voice_sum = voicing[0] + voicing[1];
914 604 : voice_diff = voicing[0] - voicing[1];
915 :
916 604 : if ( voice_diff < 0 )
917 : {
918 299 : voice_diff *= -1.0f;
919 : }
920 :
921 604 : if ( *corrFlag == 1 )
922 : {
923 26 : if ( coder_type == INACTIVE || ( ( voice_sum > 0.35 * 2 && voice_sum < 0.55 * 2 ) && ( voice_diff < 0.2 ) ) )
924 : {
925 2 : *corrFlag = 0;
926 : }
927 : }
928 604 : if ( voice_sum > 0.6 * 2 )
929 : {
930 507 : *corrFlag = 0;
931 : }
932 :
933 604 : return;
934 : }
|