Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 :
6 : #include <assert.h>
7 : #include <stdint.h>
8 : #include <memory.h>
9 : #include "options.h"
10 : #include "stat_com.h"
11 : #include "cnst.h"
12 : #include "rom_com.h"
13 : #include "prot_fx.h"
14 : #include "basop_util.h"
15 :
16 : /*----------------------------------------------------------------------------
17 : * Local constants
18 : *---------------------------------------------------------------------------*/
19 :
20 : #define HLM_MIN_NRG 32768.0f
21 : #define HLM_MIN_NRG_FX 32768 /*Q0*/
22 : #define MAX_SUBDIVISIONS 3
23 :
24 : /*----------------------------------------------------------------------------
25 : * Local prototypes
26 : *---------------------------------------------------------------------------*/
27 :
28 : /** Linear prediction analysis/synthesis filter definition.
29 : * @param order filter order.
30 : * @param parCoeff filter (PARCOR) coefficients.
31 : * @param state state of the filter. Must be at least of 'order' size.
32 : * @param x the current input value.
33 : * @return the output of the filter.
34 : */
35 : typedef Word32 ( *TLinearPredictionFilter )( Word16 order, Word16 const parCoeff[], Word32 *state, Word32 x );
36 :
37 : /** Inverse quantization for reflection coefficients.
38 : *
39 : * @param index input quantized values.
40 : * @param parCoeff output reflection coefficients.
41 : * @param order number of coefficients/values.
42 : */
43 : static void Index2Parcor( Word16 const index[], Word16 parCoeff[], Word16 order );
44 :
45 : /** Linear prediction analysis filter.
46 : * See TLinearPredictionFilter for details.
47 : */
48 : static Word32 FIRLattice( const Word16 order, const Word16 *parCoeff, Word32 *state, Word32 x );
49 :
50 : /** Linear prediction synthesis filter.
51 : * See TLinearPredictionFilter for details.
52 : */
53 : static Word32 IIRLattice( Word16 order, const Word16 *parCoeff, Word32 *state, Word32 x );
54 :
55 : /** TNS analysis/synthesis filter.
56 : * @param spectrum input spectrum values.
57 : * @param numOfLines number of lines in the spectrum.
58 : * @param parCoeff filter (PARCOR) coefficients.
59 : * @param order filter order.
60 : * @param filter function that implements filtering.
61 : By this function it is defined whether analysis or synthesis is performed.
62 : * @param output filtered output spectrum values.
63 : Inplace operation is supported, so it can be equal to spectrum.
64 : */
65 : static void TnsFilter( const Word32 spectrum[], const Word16 numOfLines, const Word16 parCoeff[], const Word16 order, TLinearPredictionFilter filter, Word32 *state, Word32 output[] );
66 :
67 : static void ITF_TnsFilter_fx( const Word32 spectrum[], const Word16 numOfLines, const Word16 A[], /* Q14 */ const Word16 Q_A, const Word16 order, Word32 output[] );
68 :
69 : static void ITF_GetFilterParameters_fx( Word32 rxx[], const Word16 maxOrder, Word16 *A, /* Q14 */ Word16 *Q_A, Word16 *predictionGain );
70 :
71 : /********************************/
72 : /* Interface functions */
73 : /********************************/
74 :
75 : /** Init TNS configuration.
76 : * Fills STnsConfig structure with sensible content.
77 : * @param nSampleRate Sampling rate of the input.
78 : * @param nFrameLength Frame length.
79 : * @param pTnsConfig TNS configuration to be initialized.
80 : * @return 0 on success, otherwise 1.
81 : */
82 51054 : void InitTnsConfiguration(
83 : const Word16 bwidth,
84 : const Word16 frameLength,
85 : STnsConfig *pTnsConfig,
86 : const Word16 igfStopFreq,
87 : const Word32 total_brate,
88 : const Word16 element_mode,
89 : const Word16 is_mct )
90 : {
91 51054 : Word16 iFilter = 0;
92 51054 : move16();
93 : Word16 *startLineFilter;
94 : Word32 L_tmp;
95 : Word32 nSampleRate;
96 : Word16 s1;
97 : Word16 s2;
98 : (void) ( element_mode );
99 : (void) ( is_mct );
100 51054 : nSampleRate = bwMode2fs[bwidth];
101 51054 : move32();
102 51054 : startLineFilter = &pTnsConfig->iFilterBorders[1];
103 :
104 : /* Sanity checks */
105 51054 : assert( ( nSampleRate > 0 ) && ( frameLength > 0 ) && ( pTnsConfig != NULL ) );
106 51054 : test();
107 51054 : test();
108 51054 : IF( ( nSampleRate <= 0 ) || ( frameLength <= 0 ) || ( pTnsConfig == NULL ) )
109 : {
110 0 : return /*TNS_FATAL_ERROR*/;
111 : }
112 :
113 :
114 : /* Initialize TNS filter flag and maximum order */
115 51054 : move16();
116 51054 : pTnsConfig->maxOrder = TNS_MAX_FILTER_ORDER;
117 :
118 51054 : IF( LE_32( total_brate, ACELP_32k ) )
119 : {
120 6768 : move16();
121 6768 : move16();
122 6768 : pTnsConfig->nMaxFilters = sizeof( tnsParametersIGF32kHz_LowBR ) / sizeof( tnsParametersIGF32kHz_LowBR[0] );
123 6768 : pTnsConfig->pTnsParameters = tnsParametersIGF32kHz_LowBR;
124 : }
125 : ELSE
126 : {
127 44286 : test();
128 44286 : IF( GT_32( nSampleRate, 32000 ) && EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) )
129 : {
130 10380 : move16();
131 10380 : pTnsConfig->nMaxFilters = sizeof( tnsParameters48kHz_grouped ) / sizeof( tnsParameters48kHz_grouped[0] );
132 10380 : move16();
133 10380 : pTnsConfig->pTnsParameters = tnsParameters48kHz_grouped;
134 : }
135 : ELSE
136 33906 : IF( GT_32( nSampleRate, INT_FS_16k ) )
137 : {
138 : {
139 :
140 31143 : move16();
141 31143 : pTnsConfig->nMaxFilters = sizeof( tnsParameters32kHz ) / sizeof( tnsParameters32kHz[0] );
142 :
143 31143 : move16();
144 31143 : pTnsConfig->pTnsParameters = tnsParameters32kHz;
145 :
146 31143 : if ( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
147 : {
148 3461 : move16();
149 3461 : pTnsConfig->pTnsParameters = tnsParameters32kHz_grouped;
150 : }
151 : }
152 : }
153 : ELSE
154 : {
155 2763 : IF( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
156 : {
157 921 : move16();
158 921 : pTnsConfig->nMaxFilters = sizeof( tnsParameters16kHz_grouped ) / sizeof( tnsParameters16kHz_grouped[0] );
159 921 : pTnsConfig->pTnsParameters = tnsParameters16kHz_grouped;
160 : }
161 : ELSE
162 : {
163 1842 : move16();
164 1842 : move16();
165 1842 : pTnsConfig->nMaxFilters = sizeof( tnsParameters16kHz ) / sizeof( tnsParameters16kHz[0] );
166 1842 : pTnsConfig->pTnsParameters = tnsParameters16kHz;
167 : }
168 : }
169 : }
170 :
171 51054 : assert( pTnsConfig->nMaxFilters <= TNS_MAX_NUM_OF_FILTERS );
172 :
173 : /* Set starting MDCT line for each filter based on the starting frequencies from the TNS table */
174 :
175 144552 : FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
176 : {
177 93498 : assert( pTnsConfig->pTnsParameters[iFilter].startLineFrequency < 0.5f * nSampleRate );
178 93498 : assert( nSampleRate <= 96000 );
179 93498 : move16();
180 93498 : startLineFilter[iFilter] = divide3232( L_mult0( frameLength, pTnsConfig->pTnsParameters[iFilter].startLineFrequency ), L_shl( nSampleRate, 14 ) );
181 : }
182 :
183 51054 : IF( igfStopFreq > 0 )
184 : {
185 38346 : L_tmp = L_mult( frameLength, igfStopFreq );
186 38346 : s1 = sub( norm_l( L_tmp ), 1 );
187 38346 : s2 = norm_l( nSampleRate );
188 :
189 38346 : move16();
190 38346 : pTnsConfig->iFilterBorders[0] = shr( div_l( L_shl( L_tmp, s1 ), extract_h( L_shl( nSampleRate, s2 ) ) ), sub( WORD16_BITS - 1, sub( s2, s1 ) ) );
191 : }
192 : ELSE
193 : {
194 12708 : move16();
195 12708 : pTnsConfig->iFilterBorders[0] = frameLength;
196 : }
197 51054 : return; /*TNS_NO_ERROR;*/
198 : }
199 :
200 87859 : void InitTnsConfiguration_ivas_fx(
201 : const Word16 bwidth, /*Q0*/
202 : const Word16 frameLength, /*Q0*/
203 : STnsConfig *pTnsConfig,
204 : const Word16 igfStopFreq, /*Q0*/
205 : const Word32 total_brate, /*Q0*/
206 : const Word16 element_mode, /*Q0*/
207 : const Word16 is_mct /*Q0*/ )
208 : {
209 87859 : Word16 iFilter = 0;
210 87859 : move16();
211 : Word16 *startLineFilter;
212 : Word32 L_tmp;
213 : Word32 nSampleRate;
214 : Word16 s1;
215 : Word16 s2;
216 :
217 87859 : nSampleRate = bwMode2fs[bwidth];
218 87859 : move32();
219 87859 : startLineFilter = &pTnsConfig->iFilterBorders[1]; /*Q0*/
220 :
221 : /* Sanity checks */
222 87859 : assert( ( nSampleRate > 0 ) && ( frameLength > 0 ) && ( pTnsConfig != NULL ) );
223 87859 : test();
224 87859 : test();
225 87859 : IF( ( nSampleRate <= 0 ) || ( frameLength <= 0 ) || ( pTnsConfig == NULL ) )
226 : {
227 0 : return /*TNS_FATAL_ERROR*/;
228 : }
229 :
230 :
231 : /* Initialize TNS filter flag and maximum order */
232 87859 : move16();
233 87859 : pTnsConfig->maxOrder = TNS_MAX_FILTER_ORDER;
234 :
235 87859 : IF( LE_32( total_brate, ACELP_32k ) )
236 : {
237 19936 : move16();
238 19936 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParametersIGF32kHz_LowBR ), sizeof( tnsParametersIGF32kHz_LowBR[0] ) ); /*Q0*/
239 19936 : pTnsConfig->pTnsParameters = tnsParametersIGF32kHz_LowBR;
240 : }
241 : ELSE
242 : {
243 67923 : test();
244 67923 : IF( GT_32( nSampleRate, 32000 ) && EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) )
245 : {
246 16777 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters48kHz_grouped ), sizeof( tnsParameters48kHz_grouped[0] ) ); /*Q0*/
247 16777 : move16();
248 16777 : pTnsConfig->pTnsParameters = tnsParameters48kHz_grouped;
249 : }
250 51146 : ELSE IF( GT_32( nSampleRate, INT_FS_16k ) )
251 : {
252 47699 : L_tmp = IVAS_32k;
253 47699 : move32();
254 47699 : if ( !is_mct )
255 : {
256 29349 : L_tmp = IVAS_48k;
257 29349 : move32();
258 : }
259 47699 : test();
260 47699 : IF( GT_16( element_mode, IVAS_SCE ) && GE_32( total_brate, L_tmp ) )
261 : {
262 37780 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters32kHz_Stereo ), sizeof( tnsParameters32kHz_Stereo[0] ) ); /*Q0*/
263 37780 : move16();
264 37780 : IF( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
265 : {
266 4320 : pTnsConfig->pTnsParameters = tnsParameters32kHz_grouped;
267 : }
268 : ELSE
269 : {
270 33460 : pTnsConfig->pTnsParameters = tnsParameters32kHz_Stereo;
271 : }
272 : }
273 : ELSE
274 : {
275 :
276 9919 : move16();
277 9919 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters32kHz ), sizeof( tnsParameters32kHz[0] ) ); /*Q0*/
278 :
279 9919 : pTnsConfig->pTnsParameters = tnsParameters32kHz;
280 :
281 9919 : if ( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
282 : {
283 395 : pTnsConfig->pTnsParameters = tnsParameters32kHz_grouped;
284 : }
285 : }
286 : }
287 : ELSE
288 : {
289 3447 : IF( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
290 : {
291 1149 : move16();
292 1149 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters16kHz_grouped ), sizeof( tnsParameters16kHz_grouped[0] ) ); /*Q0*/
293 1149 : pTnsConfig->pTnsParameters = tnsParameters16kHz_grouped;
294 : }
295 : ELSE
296 : {
297 2298 : move16();
298 2298 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters16kHz ), sizeof( tnsParameters16kHz[0] ) ); /*Q0*/
299 2298 : pTnsConfig->pTnsParameters = tnsParameters16kHz;
300 : }
301 : }
302 : }
303 :
304 87859 : assert( pTnsConfig->nMaxFilters <= TNS_MAX_NUM_OF_FILTERS );
305 :
306 : /* Set starting MDCT line for each filter based on the starting frequencies from the TNS table */
307 :
308 241343 : FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
309 : {
310 153484 : assert( pTnsConfig->pTnsParameters[iFilter].startLineFrequency < nSampleRate / 2 );
311 153484 : assert( nSampleRate <= 96000 );
312 153484 : move16();
313 153484 : startLineFilter[iFilter] = divide3232( L_mult0( frameLength, pTnsConfig->pTnsParameters[iFilter].startLineFrequency ), L_shl( nSampleRate, 14 ) ); /*Q0*/
314 : }
315 :
316 87859 : IF( igfStopFreq > 0 )
317 : {
318 69658 : L_tmp = L_mult( frameLength, igfStopFreq );
319 69658 : s1 = sub( norm_l( L_tmp ), 1 );
320 69658 : s2 = norm_l( nSampleRate );
321 :
322 69658 : move16();
323 69658 : pTnsConfig->iFilterBorders[0] = shr( div_l( L_shl( L_tmp, s1 ), extract_h( L_shl( nSampleRate, s2 ) ) ), sub( WORD16_BITS - 1, sub( s2, s1 ) ) ); /*Q0*/
324 : }
325 : ELSE
326 : {
327 18201 : move16();
328 18201 : pTnsConfig->iFilterBorders[0] = frameLength; /*Q0*/
329 : }
330 :
331 87859 : pTnsConfig->allowTnsOnWhite = 0;
332 87859 : move16();
333 :
334 87859 : return; /*TNS_NO_ERROR;*/
335 : }
336 :
337 :
338 : /*-------------------------------------------------------------------*
339 : * ApplyTnsFilter()
340 : *
341 : *-------------------------------------------------------------------*/
342 :
343 194658 : void ApplyTnsFilter(
344 : STnsConfig const *pTnsConfig,
345 : STnsData const *pTnsData,
346 : Word32 spectrum[], /*Qx*/
347 : const Word8 fIsAnalysis /*Q0*/ )
348 : {
349 : TLinearPredictionFilter filter;
350 : Word32 state[TNS_MAX_FILTER_ORDER];
351 : Word16 iFilter;
352 : Word16 stopLine, startLine;
353 : Word16 const *pBorders;
354 :
355 :
356 194658 : move16();
357 194658 : filter = IIRLattice;
358 194658 : if ( fIsAnalysis )
359 : {
360 90459 : filter = FIRLattice;
361 : }
362 194658 : set32_fx( state, 0, TNS_MAX_FILTER_ORDER );
363 194658 : move16();
364 194658 : pBorders = pTnsConfig->iFilterBorders; /*Q0*/
365 :
366 580709 : FOR( iFilter = pTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
367 : {
368 : Word16 parCoeff[TNS_MAX_FILTER_ORDER];
369 : const STnsFilter *pFilter;
370 :
371 386051 : move16();
372 386051 : move16();
373 386051 : pFilter = &pTnsData->filter[iFilter];
374 386051 : stopLine = pBorders[iFilter];
375 386051 : startLine = pBorders[iFilter + 1];
376 :
377 386051 : Index2Parcor( pFilter->coefIndex, parCoeff, pFilter->order );
378 :
379 386051 : TnsFilter( &spectrum[startLine], stopLine - startLine,
380 386051 : parCoeff, pFilter->order,
381 : filter, state,
382 386051 : &spectrum[startLine] );
383 : }
384 :
385 194658 : move16();
386 :
387 194658 : return /*result*/;
388 : }
389 :
390 : /*-------------------------------------------------------------------*
391 : * ITF_Apply()
392 : *
393 : *-------------------------------------------------------------------*/
394 :
395 496892 : void ITF_Apply_fx(
396 : Word32 spectrum[], /*Qx*/
397 : Word16 startLine, /*Q0*/
398 : Word16 stopLine, /*Q0*/
399 : const Word16 *A, /*Q_A*/
400 : Word16 Q_A,
401 : Word16 order /*Q0*/ )
402 : {
403 :
404 496892 : ITF_TnsFilter_fx( &spectrum[startLine], sub( stopLine, startLine ), A, Q_A, order, &spectrum[startLine] );
405 :
406 496892 : return /*TNS_NO_ERROR*/;
407 : }
408 : /*-------------------------------------------------------------------*
409 : * ITF_Detect()
410 : *
411 : *
412 : *-------------------------------------------------------------------*/
413 :
414 1194 : Word16 ITF_Detect_fx(
415 : const Word32 pSpectrum[], /*Q*/
416 : const Word16 startLine, /*Q0*/
417 : const Word16 stopLine, /*Q0*/
418 : const Word16 maxOrder, /*Q0*/
419 : Word16 *A, /*Q_A*/
420 : Word16 *Q_A,
421 : Word16 *predictionGain, /*Q7*/
422 : Word16 *curr_order, /*Q0*/
423 : Word16 Q )
424 : {
425 :
426 : Word16 spectrumLength;
427 1194 : Word16 const nSubdivisions = MAX_SUBDIVISIONS;
428 1194 : move16();
429 : Word16 iSubdivisions;
430 : Word16 iStartLine;
431 : Word16 iEndLine;
432 : Word16 facs[MAX_SUBDIVISIONS];
433 : Word16 facs_e[MAX_SUBDIVISIONS]; /* exponents of facs[][] */
434 : Word16 shifts[MAX_SUBDIVISIONS];
435 : Word16 tmp, headroom, shift;
436 : Word32 rxx[ITF_MAX_FILTER_ORDER + 1];
437 : Word16 lag;
438 : Word32 L_tmp, tmp32;
439 : Word16 tmpbuf[325];
440 : Word16 n, i;
441 : #ifndef ISSUE_1836_replace_overflow_libcom
442 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
443 : Flag Overflow = 0;
444 : move32();
445 : #endif
446 : #endif
447 :
448 1194 : move16();
449 1194 : move16();
450 1194 : move16();
451 :
452 1194 : if ( maxOrder <= 0 )
453 : {
454 0 : return 0;
455 : }
456 :
457 : /* Calculate norms for each spectrum part */
458 4776 : FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
459 : {
460 3582 : assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) );
461 :
462 3582 : tmp = sub( stopLine, startLine );
463 3582 : iStartLine = imult1616( tmp, iSubdivisions ); /*Q0*/
464 3582 : iEndLine = add( iStartLine, tmp );
465 :
466 3582 : if ( EQ_16( nSubdivisions, 3 ) )
467 3582 : iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/
468 3582 : iStartLine = add( iStartLine, startLine );
469 :
470 3582 : if ( EQ_16( nSubdivisions, 3 ) )
471 3582 : iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/
472 3582 : iEndLine = add( iEndLine, startLine );
473 3582 : headroom = getScaleFactor32( pSpectrum + iStartLine - IGF_START_MN, sub( iEndLine, iStartLine ) );
474 : /* Calculate norm of spectrum band */
475 3582 : L_tmp = Norm32Norm( pSpectrum + iStartLine - IGF_START_MN, headroom, sub( iEndLine, iStartLine ), &shift ); /*Q31 - shift*/
476 :
477 : /* Check threshold HLM_MIN_NRG */
478 : BASOP_SATURATE_WARNING_OFF_EVS;
479 : #ifdef ISSUE_1836_replace_overflow_libcom
480 3582 : tmp32 = L_sub( L_shl_sat( L_tmp, sub( shift, sub( 24, Q ) ) ), 4194304l /*HLM_MIN_NRG Q7*/ ); /*Q7*/
481 : #else
482 : tmp32 = L_sub( L_shl_o( L_tmp, sub( shift, sub( 24, Q ) ), &Overflow ), 4194304l /*HLM_MIN_NRG Q7*/ ); /*Q7*/
483 : #endif
484 : BASOP_SATURATE_WARNING_ON_EVS;
485 :
486 : /* get pre-shift for autocorrelation */
487 3582 : tmp = sub( shift, norm_l( L_tmp ) ); /* exponent for normalized L_tmp */
488 3582 : tmp = shr( sub( 1, tmp ), 1 ); /* pre-shift to apply before autocorrelation */
489 3582 : shifts[iSubdivisions] = s_min( tmp, headroom );
490 3582 : move16();
491 :
492 : /* calc normalization factor */
493 3582 : facs[iSubdivisions] = 0;
494 3582 : move16();
495 3582 : facs_e[iSubdivisions] = 0;
496 3582 : move16();
497 :
498 3582 : if ( tmp32 > 0 )
499 : {
500 692 : facs[iSubdivisions] = 0x7FFF;
501 692 : move16(); /* normalization not needed for one subdivision */
502 : }
503 :
504 3582 : test();
505 3582 : IF( ( tmp32 > 0 ) && ( GT_16( nSubdivisions, 1 ) ) )
506 : {
507 692 : move16();
508 692 : facs_e[iSubdivisions] = shl( sub( tmp, shifts[iSubdivisions] ), 1 );
509 :
510 692 : tmp = sub( 1, shl( tmp, 1 ) ); /* exponent of autocorrelation */
511 692 : L_tmp = L_shl( L_tmp, sub( shift, tmp ) ); /* shift L_tmp to that exponent */
512 :
513 : /* calc factor (with 2 bits headroom for sum of 3 subdivisions) */
514 692 : facs[iSubdivisions] = div_s( 0x2000, round_fx_sat( L_tmp ) ); /* L_tmp is >= 0x2000000 Q15*/
515 692 : move16();
516 : }
517 : }
518 :
519 : /* Calculate normalized autocorrelation for spectrum subdivision and get filter parameters based on it */
520 1194 : set32_fx( rxx, 0, ITF_MAX_FILTER_ORDER + 1 );
521 :
522 1194 : spectrumLength = sub( stopLine, startLine );
523 :
524 1881 : FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
525 : {
526 1766 : IF( facs[iSubdivisions] == 0 )
527 : {
528 1079 : BREAK;
529 : }
530 :
531 :
532 687 : assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) );
533 :
534 687 : iStartLine = imult1616( spectrumLength, iSubdivisions ); /*Q0*/
535 687 : iEndLine = add( iStartLine, spectrumLength ); /*Q0*/
536 :
537 687 : if ( EQ_16( nSubdivisions, 3 ) )
538 687 : iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/
539 687 : iStartLine = add( iStartLine, startLine );
540 :
541 687 : if ( EQ_16( nSubdivisions, 3 ) )
542 687 : iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/
543 687 : iEndLine = add( iEndLine, startLine );
544 :
545 :
546 687 : move16();
547 687 : shift = shifts[iSubdivisions];
548 :
549 687 : n = sub( iEndLine, iStartLine );
550 687 : assert( n < (Word16) ( sizeof( tmpbuf ) / sizeof( Word16 ) ) );
551 82015 : FOR( i = 0; i < n; i++ )
552 : {
553 81328 : tmpbuf[i] = round_fx_sat( L_shl_sat( pSpectrum[iStartLine + i - IGF_START_MN], shift ) ); /*Q + shift - 16*/
554 81328 : move16();
555 : }
556 :
557 6870 : FOR( lag = 0; lag <= maxOrder; lag++ )
558 : {
559 6183 : n = sub( sub( iEndLine, lag ), iStartLine );
560 :
561 : {
562 6183 : Word64 tmp64 = 0;
563 713403 : FOR( i = 0; i < n; i++ )
564 : {
565 707220 : tmp64 = W_mac0_16_16( tmp64, tmpbuf[i], tmpbuf[i + lag] ); /*2*(Q + shift) - 32*/
566 : }
567 6183 : L_tmp = W_sat_l( tmp64 ); /*2*(Q + shift) - 32*/
568 : }
569 :
570 6183 : L_tmp = Mpy_32_16_1( L_tmp, facs[iSubdivisions] ); /*2*(Q + shift) - 32*/
571 6183 : L_tmp = L_shl( L_tmp, facs_e[iSubdivisions] ); /*2*(Q + shift) - 32 + facs_e*/
572 :
573 6183 : rxx[lag] = L_add( rxx[lag], L_tmp );
574 6183 : move32();
575 : }
576 : }
577 :
578 1194 : IF( EQ_16( iSubdivisions, nSubdivisions ) ) /* meaning there is no subdivision with low energy */
579 : {
580 : /* Limit the maximum order to spectrum length/4 */
581 115 : ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain );
582 :
583 115 : *curr_order = maxOrder; /*Q0*/
584 115 : move16();
585 : }
586 :
587 1194 : return 1;
588 : }
589 :
590 1110031 : Word16 ITF_Detect_ivas_fx(
591 : const Word32 pSpectrum[], /*Q*/
592 : const Word16 startLine, /*Q0*/
593 : const Word16 stopLine, /*Q0*/
594 : const Word16 maxOrder, /*Q0*/
595 : Word16 *A, /*Q_A*/
596 : Word16 *Q_A,
597 : Word16 *predictionGain, /*Q7*/
598 : Word16 *curr_order, /*Q0*/
599 : Word16 Q )
600 : {
601 : Word32 norms[MAX_SUBDIVISIONS];
602 : Word16 num_subdivisions, i, length;
603 : Word16 iStartLine, iEndLine, spectrumLength;
604 : Word32 rxx[ITF_MAX_FILTER_ORDER + 1];
605 : Word16 q_rxx[ITF_MAX_FILTER_ORDER + 1];
606 : Word32 temp_spectrum[640];
607 : const Word16 *pWindow;
608 : const Word32 *ptr_spectrum1, *ptr_spectrum2;
609 : Word16 iSubdivisions, lag;
610 : Word16 headroom, guard_bits, shift, q_min;
611 : Word64 sum;
612 : Word16 fac, q_fac, exp, q_temp;
613 : Word32 temp;
614 :
615 1110031 : IF( maxOrder <= 0 )
616 : {
617 0 : return 0;
618 : }
619 1110031 : pWindow = tnsAcfWindow_fx;
620 1110031 : set_zero_fx( norms, MAX_SUBDIVISIONS );
621 1110031 : set_zero_fx( rxx, ITF_MAX_FILTER_ORDER + 1 ); /* This initialization is required */
622 1110031 : set16_fx( q_rxx, Q31, ITF_MAX_FILTER_ORDER + 1 ); /* This initialization is required */
623 :
624 1110031 : spectrumLength = sub( stopLine, startLine );
625 1110031 : num_subdivisions = 0;
626 1110031 : move16();
627 :
628 : /* Calculate norms for each spectrum part */
629 1796558 : FOR( iSubdivisions = 0; iSubdivisions < MAX_SUBDIVISIONS; iSubdivisions++ )
630 : {
631 : /* iStartLine = startLine + ( stopLine - startLine ) * iSubdivisions / nSubdivisions; */
632 1625422 : iStartLine = add( startLine, mult( imult1616( spectrumLength, iSubdivisions ), 10923 /* 1/MAX_SUBDIVISIONS in Q15 */ ) ); /*Q0*/
633 : /* iEndLine = startLine + ( stopLine - startLine ) * ( iSubdivisions + 1 ) / nSubdivisions; */
634 1625422 : iEndLine = add( startLine, mult( imult1616( spectrumLength, add( iSubdivisions, 1 ) ), 10923 /* 1/MAX_SUBDIVISIONS in Q15 */ ) ); /*Q0*/
635 :
636 :
637 : /* Variable initialization */
638 : /* norms[iSubdivisions] = sum2_f(pSpectrum + iStartLine - IGF_START_MN, iEndLine - iStartLine); */
639 :
640 1625422 : ptr_spectrum1 = pSpectrum + sub( iStartLine, IGF_START_MN );
641 1625422 : length = sub( iEndLine, iStartLine );
642 1625422 : headroom = L_norm_arr( ptr_spectrum1, length );
643 1625422 : guard_bits = find_guarded_bits_fx( length );
644 1625422 : shift = sub( headroom, guard_bits );
645 :
646 1625422 : Copy_Scale_sig32( ptr_spectrum1, temp_spectrum, length, shift ); // Q -> Q+shift
647 :
648 1625422 : sum = 0;
649 1625422 : move64();
650 166540409 : FOR( i = 0; i < length; i++ )
651 : {
652 164914987 : sum = W_mac_32_32( sum, temp_spectrum[i], temp_spectrum[i] ); // 2(Q+shift)+1
653 : }
654 1625422 : IF( LE_64( sum, W_shl( 32768 * 2 /* HLM_MIN_NRG in Q1 */, s_min( 63, shl( add( Q, shift ), 1 ) ) ) ) )
655 : {
656 938895 : BREAK;
657 : }
658 :
659 : /* fac = 1.0f / norms[iSubdivisions]; */
660 686527 : exp = W_norm( sum );
661 686527 : sum = W_shl( sum, exp ); // 2(Q+shift)+1+exp
662 686527 : fac = div_s( ONE_IN_Q14, extract_h( W_extract_h( sum ) ) ); // 15+14-(2(Q+shift)+1+exp-48) = 76-(2(Q+shift)+exp)
663 686527 : q_fac = sub( 76, add( shl( add( Q, shift ), 1 ), exp ) );
664 686527 : pWindow = tnsAcfWindow_fx;
665 :
666 : /* For additional loop condition */
667 : /* Variable initialization */
668 : /*for ( lag = 1; lag <= maxOrder; lag++ )
669 : {
670 : rxx[lag] += fac * ( *pWindow ) * dotp( pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag );
671 : pWindow++;
672 : }*/
673 :
674 686527 : ptr_spectrum1 = temp_spectrum; // pSpectrum + iStartLine - IGF_START_MN;
675 6178743 : FOR( lag = 1; lag <= maxOrder; lag++ )
676 : {
677 : /* dotp( pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag ) */
678 5492216 : ptr_spectrum2 = temp_spectrum + lag; // pSpectrum + iStartLine - IGF_START_MN + lag;
679 :
680 5492216 : sum = 0;
681 5492216 : move64();
682 589466716 : FOR( i = 0; i < iEndLine - iStartLine - lag; i++ )
683 : {
684 583974500 : sum = W_mac_32_32( sum, ptr_spectrum1[i], ptr_spectrum2[i] ); // 2(Q+shift)+1
685 : }
686 5492216 : exp = W_norm( sum );
687 5492216 : sum = W_shl( sum, exp ); // 2(Q+shift)+1+exp
688 5492216 : temp = Mpy_32_32( L_mult0( fac, *pWindow ), W_extract_h( sum ) ); // (q_fac+15)+(2(Q+shift)+1+exp-32)-31 = q_fac+2(Q+shift)+exp-47
689 5492216 : q_temp = sub( add( q_fac, add( shl( add( Q, shift ), 1 ), exp ) ), 47 );
690 :
691 : /* rxx[lag] += fac * (*pWindow) * dotp(pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag); */
692 5492216 : q_min = sub( s_min( q_temp, q_rxx[lag] ), 1 );
693 5492216 : rxx[lag] = L_add( L_shl( rxx[lag], sub( q_min, q_rxx[lag] ) ), L_shl( temp, sub( q_min, q_temp ) ) );
694 5492216 : q_rxx[lag] = q_min;
695 5492216 : move32();
696 5492216 : move16();
697 :
698 5492216 : pWindow++;
699 : }
700 :
701 686527 : num_subdivisions = add( num_subdivisions, 1 );
702 : }
703 :
704 1110031 : minimum_s( q_rxx + 1, ITF_MAX_FILTER_ORDER, &q_min );
705 1110031 : q_min = s_min( Q29, q_min );
706 :
707 17760496 : FOR( i = 1; i < ITF_MAX_FILTER_ORDER; i++ )
708 : {
709 16650465 : rxx[i] = L_shl( rxx[i], sub( q_min, q_rxx[i] ) );
710 16650465 : move32();
711 : }
712 :
713 1110031 : IF( EQ_16( iSubdivisions, MAX_SUBDIVISIONS ) ) /* meaning there is no subdivision with low energy */
714 : {
715 171136 : rxx[0] = L_shl( MAX_SUBDIVISIONS, q_min );
716 171136 : move32();
717 :
718 : /* Limit the maximum order to spectrum length/4 */
719 171136 : ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain );
720 :
721 171136 : *curr_order = maxOrder; /*Q0*/
722 171136 : move16();
723 : }
724 :
725 1110031 : return 1;
726 : }
727 : /* Helper functions for Hufmann table coding */
728 :
729 :
730 : /** Get number of bits from a Huffman table.
731 : * The table must be sorted by values.
732 : */
733 1494548 : static Word16 GetBitsFromTable( const Word16 value /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
734 : {
735 : (void) nSize;
736 1494548 : assert( ( value >= 0 ) && ( value < nSize ) && ( nSize >= 0 ) && ( nSize <= 256 ) );
737 :
738 1494548 : move16();
739 1494548 : cast16();
740 1494548 : return (Word16) codes[value].nBits; /*Q0*/
741 : }
742 :
743 : /** Get the code for a value from a Huffman table.
744 : * The table must be sorted by values.
745 : */
746 738544 : static Word16 EncodeUsingTable( const Word16 value /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
747 : {
748 : (void) nSize;
749 738544 : assert( ( value >= 0 ) && ( value < nSize ) && ( nSize >= 0 ) && ( nSize <= 256 ) );
750 :
751 738544 : move16();
752 738544 : return codes[value].code; /*Q0*/
753 : }
754 :
755 :
756 : /** Decode a value from a bitstream using a Huffman table. */
757 708136 : static Word16 DecodeUsingTable( Decoder_State *st, Word16 *pValue /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
758 : {
759 708136 : Word16 code = 0;
760 708136 : Word16 nBits = 0;
761 708136 : move16();
762 708136 : move16();
763 : Word16 valueIndex;
764 :
765 708136 : assert( ( nSize >= 0 ) && ( nSize <= 256 ) );
766 :
767 :
768 708136 : move16();
769 708136 : valueIndex = nSize;
770 :
771 :
772 2548892 : WHILE( valueIndex == nSize )
773 : {
774 1840756 : code = add( shl( code, 1 ), get_next_indice_fx( st, 1 ) ); /*Q0*/
775 1840756 : nBits = add( nBits, 1 );
776 1840756 : test();
777 1840756 : IF( GT_16( nBits, nSize ) || GT_16( nBits, 16 ) )
778 : {
779 0 : st->BER_detect = 1;
780 0 : move16();
781 0 : *pValue = 0;
782 0 : move16();
783 :
784 0 : return -1;
785 : }
786 :
787 23676892 : FOR( valueIndex = 0; valueIndex < nSize; valueIndex++ )
788 : {
789 :
790 22544272 : IF( s_and( (Word16) EQ_16( codes[valueIndex].nBits, nBits ), (Word16) EQ_16( codes[valueIndex].code, code ) ) )
791 : {
792 708136 : BREAK;
793 : }
794 : }
795 : }
796 708136 : IF( LT_16( valueIndex, nSize ) )
797 : {
798 708136 : *pValue = (Word16) codes[valueIndex].value; /*Q0*/
799 708136 : move16();
800 : }
801 : ELSE
802 : {
803 0 : st->BER_detect = 1;
804 0 : move16();
805 0 : *pValue = 0;
806 0 : move16();
807 0 : return -1;
808 : }
809 :
810 708136 : return nBits; /*Q0*/
811 : }
812 :
813 :
814 : /* TNS filter coefficients */
815 :
816 457458 : Word16 DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
817 : {
818 457458 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
819 457458 : return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes );
820 : }
821 :
822 133547 : Word16 DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
823 : {
824 133547 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
825 133547 : return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes );
826 : }
827 :
828 8504 : Word16 DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
829 : {
830 8504 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
831 8504 : return DecodeUsingTable( st, pValue, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes );
832 : }
833 :
834 :
835 : /* TNS filter order */
836 :
837 79237 : Word16 DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
838 : {
839 : (void) index;
840 79237 : return DecodeUsingTable( st, pValue, codesTnsOrderTCX20, nTnsOrderCodes );
841 : }
842 :
843 0 : Word16 GetTnsFilterOrderBitsSWBTCX10_flt( const Word16 value, const Word16 index )
844 : {
845 : (void) index;
846 0 : return GetBitsFromTable( value - 1, codesTnsOrderTCX10, nTnsOrderCodes );
847 : }
848 :
849 0 : Word16 EncodeTnsFilterOrderSWBTCX10_flt( const Word16 value, const Word16 index )
850 : {
851 : (void) index;
852 0 : return EncodeUsingTable( value - 1, codesTnsOrderTCX10, nTnsOrderCodes );
853 : }
854 :
855 28025 : Word16 DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
856 : {
857 : (void) index;
858 28025 : return DecodeUsingTable( st, pValue, codesTnsOrderTCX10, nTnsOrderCodes );
859 : }
860 :
861 :
862 639656 : void const *GetTnsFilterCoeff( void const *p, const Word16 index /*Q0*/, Word16 *pValue /*Q0*/ )
863 : {
864 639656 : *pValue = ( (Word16 const *) p )[index] + INDEX_SHIFT;
865 639656 : move16();
866 639656 : return NULL;
867 : }
868 :
869 614141 : void *SetTnsFilterCoeff( void *p, const Word16 index /*Q0*/, const Word16 value /*Q0*/ )
870 : {
871 614141 : ( (Word16 *) p )[index] = sub( value, INDEX_SHIFT );
872 614141 : move16();
873 614141 : return NULL;
874 : }
875 :
876 :
877 965364 : Word16 GetSWBTCX20TnsFilterCoeffBits( const Word16 value, const Word16 index )
878 : {
879 965364 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
880 :
881 965364 : return GetBitsFromTable( value, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
882 : }
883 :
884 476987 : Word16 EncodeSWBTCX20TnsFilterCoeff( const Word16 value, const Word16 index )
885 : {
886 476987 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
887 :
888 476987 : return EncodeUsingTable( value, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
889 : }
890 :
891 0 : Word16 DecodeSWBTCX20TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
892 : {
893 0 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
894 :
895 0 : return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
896 : }
897 :
898 281790 : Word16 GetSWBTCX10TnsFilterCoeffBits( const Word16 value, const Word16 index )
899 : {
900 281790 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
901 :
902 281790 : return GetBitsFromTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
903 : }
904 :
905 139335 : Word16 EncodeSWBTCX10TnsFilterCoeff( const Word16 value, const Word16 index )
906 : {
907 139335 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
908 :
909 139335 : return EncodeUsingTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
910 : }
911 :
912 0 : Word16 DecodeSWBTCX10TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
913 : {
914 0 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
915 :
916 0 : return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
917 : }
918 :
919 17600 : Word16 GetWBTCX20TnsFilterCoeffBits( const Word16 value, const Word16 index )
920 : {
921 17600 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
922 :
923 17600 : return GetBitsFromTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
924 : }
925 :
926 8776 : Word16 EncodeWBTCX20TnsFilterCoeff( const Word16 value, const Word16 index )
927 : {
928 8776 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
929 :
930 8776 : return EncodeUsingTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
931 : }
932 :
933 0 : Word16 DecodeWBTCX20TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
934 : {
935 0 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
936 :
937 0 : return DecodeUsingTable( st, pValue, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
938 : }
939 :
940 :
941 : /* TNS filter order */
942 :
943 116348 : void const *GetTnsFilterOrder( void const *p, const Word16 index, Word16 *pValue )
944 : {
945 116348 : move16();
946 116348 : *pValue = ( (STnsFilter const *) p )[index].order; /*Q0*/
947 :
948 116348 : move16();
949 116348 : return ( (STnsFilter const *) p )[index].coefIndex; /*Q0*/
950 : }
951 :
952 111542 : void *SetTnsFilterOrder( void *p, const Word16 index, const Word16 value )
953 : {
954 111542 : move16();
955 111542 : ( (STnsFilter *) p )[index].order = value; /*Q0*/
956 :
957 111542 : move16();
958 111542 : return ( (STnsFilter *) p )[index].coefIndex; /*Q0*/
959 : }
960 :
961 167621 : Word16 GetTnsFilterOrderBitsSWBTCX20( const Word16 value, const Word16 index )
962 : {
963 : (void) index;
964 :
965 167621 : return GetBitsFromTable( sub( value, 1 ), codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
966 : }
967 :
968 82756 : Word16 EncodeTnsFilterOrderSWBTCX20( const Word16 value, const Word16 index )
969 : {
970 : (void) index;
971 :
972 82756 : return EncodeUsingTable( sub( value, 1 ), codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
973 : }
974 :
975 0 : Word16 DecodeTnsFilterOrderSWBTCX20( Decoder_State *st, const Word16 index, Word16 *pValue )
976 : {
977 : (void) index;
978 :
979 0 : return DecodeUsingTable( st, pValue, codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
980 : }
981 :
982 59344 : Word16 GetTnsFilterOrderBitsSWBTCX10( const Word16 value, const Word16 index )
983 : {
984 : (void) index;
985 :
986 59344 : return GetBitsFromTable( sub( value, 1 ), codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
987 : }
988 :
989 29280 : Word16 EncodeTnsFilterOrderSWBTCX10( const Word16 value, const Word16 index )
990 : {
991 : (void) index;
992 :
993 29280 : return EncodeUsingTable( sub( value, 1 ), codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
994 : }
995 :
996 0 : Word16 DecodeTnsFilterOrderSWBTCX10( Decoder_State *st, const Word16 index, Word16 *pValue )
997 : {
998 : (void) index;
999 :
1000 0 : return DecodeUsingTable( st, pValue, codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
1001 : }
1002 :
1003 2829 : Word16 GetTnsFilterOrderBits( const Word16 value, const Word16 index )
1004 : {
1005 : (void) index;
1006 :
1007 2829 : return GetBitsFromTable( sub( value, 1 ), codesTnsOrder, nTnsOrderCodes ); /*Q0*/
1008 : }
1009 :
1010 1410 : Word16 EncodeTnsFilterOrder( const Word16 value, const Word16 index )
1011 : {
1012 : (void) index;
1013 :
1014 1410 : return EncodeUsingTable( sub( value, 1 ), codesTnsOrder, nTnsOrderCodes ); /*Q0*/
1015 : }
1016 :
1017 0 : Word16 DecodeTnsFilterOrder( Decoder_State *st, const Word16 index, Word16 *pValue )
1018 : {
1019 : (void) index;
1020 :
1021 0 : return DecodeUsingTable( st, pValue, codesTnsOrder, nTnsOrderCodes ); /*Q0*/
1022 : }
1023 :
1024 : /* Number of TNS filters */
1025 :
1026 0 : void const *GetNumOfTnsFilters( void const *p, const Word16 index, Word16 *pValue )
1027 : {
1028 0 : move16();
1029 0 : *pValue = ( (STnsData const *) p )[index].nFilters; /*Q0*/
1030 0 : move16();
1031 0 : return ( (STnsData const *) p )[index].filter;
1032 : }
1033 :
1034 0 : void *SetNumOfTnsFilters( void *p, const Word16 index, Word16 value )
1035 : {
1036 0 : move16();
1037 0 : ( (STnsData *) p )[index].nFilters = value; /*Q0*/
1038 0 : move16();
1039 0 : return ( (STnsData *) p )[index].filter;
1040 : }
1041 :
1042 : /* TNS enabled/disabled flag */
1043 :
1044 1292407 : void const *GetTnsEnabled( void const *p, const Word16 index, Word16 *pValue )
1045 : {
1046 1292407 : move16();
1047 1292407 : *pValue = 0;
1048 1292407 : if ( ( (STnsData const *) p )[index].nFilters != 0 )
1049 : {
1050 88988 : move16();
1051 88988 : *pValue = 1;
1052 : }
1053 1292407 : return NULL;
1054 : }
1055 :
1056 677907 : void *SetTnsEnabled( void *p, const Word16 index, const Word16 value )
1057 : {
1058 : (void) p, (void) index, (void) value;
1059 677907 : return NULL;
1060 : }
1061 :
1062 : /* Number of TNS filters */
1063 :
1064 88988 : void const *GetNumOfTnsFilters_flt( void const *p, const Word16 index, Word16 *pValue )
1065 : {
1066 88988 : *pValue = (Word16) abs( ( (STnsData const *) p )[index].nFilters );
1067 88988 : return ( (STnsData const *) p )[index].filter;
1068 : }
1069 :
1070 85432 : void *SetNumOfTnsFilters_flt( void *p, const Word16 index, const Word16 value )
1071 : {
1072 85432 : ( (STnsData *) p )[index].nFilters = (Word16) abs( value );
1073 85432 : return ( (STnsData *) p )[index].filter;
1074 : }
1075 1365 : Word16 DecodeTnsFilterOrder_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
1076 : {
1077 : (void) index;
1078 1365 : return DecodeUsingTable( st, pValue, codesTnsOrder, nTnsOrderCodes );
1079 : }
1080 : /* TNS on whitened spectra flag */
1081 :
1082 71736 : void const *GetTnsOnWhite( void const *p, const Word16 index, Word16 *pValue )
1083 : {
1084 71736 : *pValue = ( (STnsData const *) p )[index].tnsOnWhitenedSpectra > 0 ? 1 : 0;
1085 71736 : return NULL;
1086 : }
1087 :
1088 69216 : void *SetTnsOnWhite( void *p, const Word16 index, const Word16 value )
1089 : {
1090 69216 : ( (STnsData *) p )[index].tnsOnWhitenedSpectra = value;
1091 69216 : return NULL;
1092 : }
1093 :
1094 167128 : void const *GetTnsEnabledSingleFilter( void const *p, const Word16 index, Word16 *pValue )
1095 : {
1096 167128 : move16();
1097 167128 : *pValue = 0;
1098 167128 : if ( ( (STnsData const *) p )[index].nFilters > 0 )
1099 : {
1100 1419 : move16();
1101 1419 : *pValue = 1;
1102 : }
1103 167128 : return ( (STnsData const *) p )[index].filter;
1104 : }
1105 :
1106 99949 : void *SetTnsEnabledSingleFilter( void *p, const Word16 index, const Word16 value )
1107 : {
1108 99949 : ( (STnsData *) p )[index].nFilters = value; /*Q0*/
1109 99949 : move16();
1110 99949 : return ( (STnsData *) p )[index].filter;
1111 : }
1112 :
1113 : /*-------------------------------------------------------------------*
1114 : * ResetTnsData()
1115 : *
1116 : *-------------------------------------------------------------------*/
1117 :
1118 2237391 : void ResetTnsData( STnsData *pTnsData )
1119 : {
1120 : Word16 iFilter;
1121 :
1122 :
1123 2237391 : pTnsData->nFilters = 0;
1124 2237391 : move16();
1125 2237391 : pTnsData->tnsOnWhitenedSpectra = 0;
1126 2237391 : move16();
1127 6712173 : FOR( iFilter = 0; iFilter < (Word16) ( sizeof( pTnsData->filter ) / sizeof( pTnsData->filter[0] ) ); iFilter++ )
1128 : {
1129 4474782 : STnsFilter *const pTnsFilter = &pTnsData->filter[iFilter];
1130 4474782 : pTnsFilter->spectrumLength = 0;
1131 4474782 : move16();
1132 4474782 : pTnsFilter->predictionGain = ONE_IN_Q7; /*Q7*/
1133 4474782 : move16();
1134 4474782 : pTnsFilter->predictionGain32 = ONE_IN_Q23; /*Q23*/
1135 4474782 : move32();
1136 4474782 : pTnsFilter->predictionGain_e = PRED_GAIN_E;
1137 4474782 : move16();
1138 4474782 : pTnsFilter->avgSqrCoef = 0;
1139 4474782 : move16();
1140 4474782 : pTnsFilter->filterType = TNS_FILTER_OFF; /*Q0*/
1141 4474782 : move16();
1142 4474782 : ClearTnsFilterCoefficients( pTnsFilter );
1143 : }
1144 2237391 : }
1145 : /*-------------------------------------------------------------------*
1146 : * ClearTnsFilterCoefficients()
1147 : *
1148 : *-------------------------------------------------------------------*/
1149 :
1150 8344885 : void ClearTnsFilterCoefficients(
1151 : STnsFilter *pTnsFilter )
1152 : {
1153 8344885 : move16();
1154 8344885 : pTnsFilter->order = 0;
1155 8344885 : move16();
1156 : assert( TNS_MAX_FILTER_ORDER == 8 );
1157 8344885 : move16();
1158 8344885 : move16();
1159 8344885 : move16();
1160 8344885 : move16();
1161 8344885 : move16();
1162 8344885 : move16();
1163 8344885 : move16();
1164 8344885 : move16();
1165 8344885 : pTnsFilter->coefIndex[0] = 0;
1166 8344885 : pTnsFilter->coefIndex[1] = 0;
1167 8344885 : pTnsFilter->coefIndex[2] = 0;
1168 8344885 : pTnsFilter->coefIndex[3] = 0;
1169 8344885 : pTnsFilter->coefIndex[4] = 0;
1170 8344885 : pTnsFilter->coefIndex[5] = 0;
1171 8344885 : pTnsFilter->coefIndex[6] = 0;
1172 8344885 : pTnsFilter->coefIndex[7] = 0;
1173 8344885 : }
1174 :
1175 : /** Inverse quantization for reflection coefficients.
1176 : *
1177 : * @param index input quantized values.
1178 : * @param parCoeff output reflection coefficients.
1179 : * @param order number of coefficients/values.
1180 : */
1181 386051 : static void Index2Parcor( const Word16 index[] /*Q0*/, Word16 parCoeff[] /*Q15*/, Word16 order /*Q0*/ )
1182 : {
1183 : const Word16 *values;
1184 : Word16 i;
1185 :
1186 386051 : move16();
1187 386051 : values = tnsCoeff4; /*Q15*/
1188 :
1189 1774118 : FOR( i = 0; i < order; i++ )
1190 : {
1191 1388067 : move16();
1192 1388067 : parCoeff[i] = values[( index[i] + INDEX_SHIFT )]; /*Q15*/
1193 : }
1194 386051 : return;
1195 : }
1196 :
1197 :
1198 : /* Linear prediction analysis filter. */
1199 51547574 : static Word32 FIRLattice(
1200 : const Word16 order, /*Q0*/
1201 : const Word16 *parCoeff /*Q15*/,
1202 : Word32 *state, /*Q0*/
1203 : Word32 x /* Q0 */
1204 : )
1205 : {
1206 : Word16 i;
1207 : Word32 tmpSave, tmp;
1208 :
1209 :
1210 51547574 : tmpSave = x;
1211 51547574 : move32();
1212 286797940 : FOR( i = 0; i < order - 1; i++ )
1213 : {
1214 235250366 : tmp = Madd_32_16( state[i], x, parCoeff[i] ); /*Q0*/
1215 235250366 : x = Madd_32_16( x, state[i], parCoeff[i] ); /* exponent: 31+0 */
1216 235250366 : state[i] = tmpSave; /*Q0*/
1217 235250366 : move32();
1218 235250366 : tmpSave = tmp; /*Q0*/
1219 235250366 : move32();
1220 : }
1221 :
1222 : /* last stage: only need half operations */
1223 51547574 : x = Madd_32_16( x, state[order - 1], parCoeff[order - 1] ); /*Q0*/
1224 51547574 : state[order - 1] = tmpSave; /*Q0*/
1225 51547574 : move32();
1226 :
1227 51547574 : return x; /*Q0*/
1228 : }
1229 :
1230 60439871 : static Word32 IIRLattice( Word16 order /*Q0*/, const Word16 *parCoeff /*Q15*/, Word32 *state /*Q0*/, Word32 x /*Q0*/ )
1231 : {
1232 : Word16 i;
1233 :
1234 :
1235 : /* first stage: no need to calculate state[order-1] */
1236 60439871 : x = Msub_32_16( x, state[order - 1], parCoeff[order - 1] ); /*Q0*/
1237 :
1238 331786376 : FOR( i = order - 2; i >= 0; i-- )
1239 : {
1240 271346505 : x = Msub_32_16( x, state[i], parCoeff[i] ); /*Q0*/
1241 271346505 : state[i + 1] = Madd_32_16( state[i], x, parCoeff[i] ); /*Q0*/
1242 271346505 : move32();
1243 : }
1244 :
1245 60439871 : move32();
1246 60439871 : state[0] = x; /*Q0*/
1247 60439871 : return x; /*Q0*/
1248 : }
1249 : /** TNS analysis/synthesis filter.
1250 : * @param spectrum input spectrum values.
1251 : * @param numOfLines number of lines in the spectrum.
1252 : * @param parCoeff filter (PARCOR) coefficients.
1253 : * @param order filter order.
1254 : * @param filter function that implements filtering.
1255 : By this function it is defined whether analysis or synthesis is performed.
1256 : * @param output filtered output spectrum values.
1257 : Inplace operation is supported, so it can be equal to spectrum.
1258 : */
1259 386051 : static void TnsFilter(
1260 : const Word32 spectrum[], /*Qx*/
1261 : const Word16 numOfLines, /*Q0*/
1262 : const Word16 parCoeff[], /*Q15*/
1263 : const Word16 order, /*Q0*/
1264 : TLinearPredictionFilter filter,
1265 : Word32 *state, /*Q0*/
1266 : Word32 output[] /*Qx*/ )
1267 : {
1268 : Word16 j;
1269 :
1270 :
1271 386051 : assert( ( order >= 0 ) && ( order <= TNS_MAX_FILTER_ORDER ) );
1272 386051 : assert( ( numOfLines > 0 ) || ( ( numOfLines == 0 ) && ( order == 0 ) ) );
1273 :
1274 386051 : IF( order == 0 )
1275 : {
1276 :
1277 133126 : test();
1278 133126 : IF( s_and( ( spectrum != output ), numOfLines > 0 ) )
1279 : {
1280 0 : Copy32( spectrum, output, numOfLines ); /*Qx*/
1281 : }
1282 : }
1283 : ELSE
1284 : {
1285 : {
1286 :
1287 112240370 : FOR( j = 0; j < numOfLines; j++ )
1288 : {
1289 111987445 : move32();
1290 111987445 : output[j] = filter( order, parCoeff, state, spectrum[j] ); /*Qx*/
1291 : }
1292 : }
1293 : }
1294 386051 : return;
1295 : }
1296 :
1297 496892 : static void ITF_TnsFilter_fx(
1298 : const Word32 spectrum[], /*Qx*/
1299 : const Word16 numOfLines, /*Q0*/
1300 : const Word16 A[], /* ifdef FIX_ITF_OVERFLOW Q_A else Q14 */
1301 : const Word16 Q_A,
1302 : const Word16 order, /*Q0*/
1303 : Word32 output[] /*Qx*/ )
1304 : {
1305 : Word16 i, j;
1306 : Word32 buf[ITF_MAX_FILTER_ORDER + N_MAX];
1307 : Word32 *p;
1308 : Word16 shift;
1309 496892 : assert( ( order >= 0 ) && ( order <= ITF_MAX_FILTER_ORDER ) );
1310 496892 : assert( ( numOfLines > 0 ) || ( ( numOfLines == 0 ) && ( order == 0 ) ) );
1311 :
1312 496892 : IF( order == 0 )
1313 : {
1314 :
1315 429238 : test();
1316 429238 : IF( s_and( ( spectrum != output ), numOfLines > 0 ) )
1317 : {
1318 0 : Copy32( spectrum, output, numOfLines ); /*Qx*/
1319 : }
1320 : }
1321 : ELSE
1322 : {
1323 67654 : shift = sub( 15, Q_A );
1324 :
1325 67654 : p = buf + ITF_MAX_FILTER_ORDER;
1326 67654 : set32_fx( buf, 0, ITF_MAX_FILTER_ORDER );
1327 67654 : Copy32( spectrum, p, numOfLines ); /*Qx*/
1328 22277182 : FOR( j = 0; j < numOfLines; j++ )
1329 : {
1330 : Word32 L_tmp;
1331 :
1332 22209528 : L_tmp = L_add( p[0], 0 );
1333 177676224 : FOR( i = 1; i < order; i++ )
1334 : {
1335 155466696 : L_tmp = L_add_sat( L_tmp, L_shl( Mpy_32_16_1( p[-i], A[i] ), shift ) ); /*Qx*/
1336 : }
1337 22209528 : output[j] = L_tmp; /*Qx*/
1338 22209528 : move32();
1339 22209528 : ++p;
1340 : }
1341 : }
1342 496892 : return;
1343 : }
1344 :
1345 171251 : static void ITF_GetFilterParameters_fx(
1346 : Word32 rxx[], /*Qx*/
1347 : const Word16 maxOrder, /*Q0*/
1348 : Word16 *A, /* ifdef FIX_ITF_OVERFLOW Q_A else Q14 */
1349 : Word16 *Q_A,
1350 : Word16 *predictionGain /*Q7*/ )
1351 : {
1352 : Word16 i, j, i_2, tmp;
1353 : Word16 parCoeff[ITF_MAX_FILTER_ORDER];
1354 : Word32 epsP[ITF_MAX_FILTER_ORDER + 1], L_tmp;
1355 :
1356 : /* compute filter in ParCor form with LeRoux-Gueguen algorithm */
1357 171251 : L_tmp = E_LPC_schur( rxx, parCoeff, epsP, maxOrder );
1358 : BASOP_SATURATE_WARNING_OFF_EVS /* Allow saturation, this value is compared against a threshold. */
1359 171251 : *predictionGain = divide3232( L_shr( epsP[0], PRED_GAIN_E ), L_tmp ); /*Q7*/
1360 171251 : move16();
1361 : BASOP_SATURATE_WARNING_ON_EVS
1362 :
1363 : {
1364 : Word32 A32[ITF_MAX_FILTER_ORDER];
1365 : Word16 tmp1_l, tmp1_h, tmp2_l, tmp2_h;
1366 :
1367 : /* Convert ParCor / reflection coefficients to LPC */
1368 171251 : A32[0] = 134217728l /*1.0 Q27*/;
1369 171251 : move32(); /* Q11+16 */
1370 171251 : A32[1] = L_shr( L_deposit_h( parCoeff[0] ), 4 ); /* Q11+16 */
1371 171251 : move32();
1372 :
1373 1370008 : FOR( i = 1; i < maxOrder; i++ )
1374 : {
1375 1198757 : L_tmp = L_shr( L_deposit_h( parCoeff[i] ), 3 ); /* Q11+16 */
1376 :
1377 1198757 : i_2 = shr( i, 1 );
1378 3253769 : FOR( j = 0; j < i_2; j++ )
1379 : {
1380 2055012 : tmp1_l = L_Extract_lc( A32[i - 1 - j + 1], &tmp1_h );
1381 2055012 : tmp2_l = L_Extract_lc( A32[j + 1], &tmp2_h );
1382 2055012 : A32[j + 1] = Mac_32( A32[j + 1], parCoeff[i], 0, tmp1_h, tmp1_l ); /*+= parCoeff[i] * a[i-1-j+1]; Q11+16*/
1383 2055012 : move32();
1384 2055012 : A32[i - 1 - j + 1] = Mac_32( A32[i - 1 - j + 1], parCoeff[i], 0, tmp2_h, tmp2_l ); /*+= parCoeff[i] * tmp; Q11+16*/
1385 2055012 : move32();
1386 : }
1387 1198757 : IF( s_and( i, 1 ) )
1388 : {
1389 685004 : tmp2_l = L_Extract_lc( A32[j + 1], &tmp2_h );
1390 685004 : A32[j + 1] = Mac_32( A32[j + 1], parCoeff[i], 0, tmp2_h, tmp2_l ); /*+= parCoeff[i] * a[j+1]; Q11+16*/
1391 685004 : move32();
1392 : }
1393 :
1394 1198757 : A32[i + 1] = L_shr( L_deposit_h( parCoeff[i] ), 4 ); /* Q11+16 */
1395 1198757 : move32();
1396 : }
1397 :
1398 171251 : tmp = 3;
1399 171251 : move16(); /* assume Q11 -> Q14 */
1400 1541259 : FOR( i = 0; i < maxOrder; i++ )
1401 : {
1402 1370008 : tmp = s_min( tmp, norm_l( A32[i] ) );
1403 : }
1404 1541259 : FOR( i = 0; i < maxOrder; i++ )
1405 : {
1406 1370008 : A[i] = round_fx( L_shl( A32[i], tmp ) ); /* Q11+tmp */
1407 1370008 : move16();
1408 : }
1409 171251 : *Q_A = add( 11, tmp );
1410 171251 : move16();
1411 : }
1412 171251 : return;
1413 : }
|