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