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 51068 : 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 51068 : Word16 iFilter = 0;
92 51068 : 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 51068 : nSampleRate = bwMode2fs[bwidth];
101 51068 : move32();
102 51068 : startLineFilter = &pTnsConfig->iFilterBorders[1];
103 :
104 : /* Sanity checks */
105 51068 : assert( ( nSampleRate > 0 ) && ( frameLength > 0 ) && ( pTnsConfig != NULL ) );
106 51068 : test();
107 51068 : test();
108 51068 : 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 51068 : move16();
116 51068 : pTnsConfig->maxOrder = TNS_MAX_FILTER_ORDER;
117 :
118 51068 : IF( LE_32( total_brate, ACELP_32k ) )
119 : {
120 6692 : move16();
121 6692 : move16();
122 6692 : pTnsConfig->nMaxFilters = sizeof( tnsParametersIGF32kHz_LowBR ) / sizeof( tnsParametersIGF32kHz_LowBR[0] );
123 6692 : pTnsConfig->pTnsParameters = tnsParametersIGF32kHz_LowBR;
124 : }
125 : ELSE
126 : {
127 44376 : test();
128 44376 : IF( GT_32( nSampleRate, 32000 ) && EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) )
129 : {
130 10379 : move16();
131 10379 : pTnsConfig->nMaxFilters = sizeof( tnsParameters48kHz_grouped ) / sizeof( tnsParameters48kHz_grouped[0] );
132 10379 : move16();
133 10379 : pTnsConfig->pTnsParameters = tnsParameters48kHz_grouped;
134 : }
135 : ELSE
136 33997 : IF( GT_32( nSampleRate, INT_FS_16k ) )
137 : {
138 : {
139 :
140 31234 : move16();
141 31234 : pTnsConfig->nMaxFilters = sizeof( tnsParameters32kHz ) / sizeof( tnsParameters32kHz[0] );
142 :
143 31234 : move16();
144 31234 : pTnsConfig->pTnsParameters = tnsParameters32kHz;
145 :
146 31234 : if ( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
147 : {
148 3492 : move16();
149 3492 : 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 51068 : 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 144670 : FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
176 : {
177 93602 : assert( pTnsConfig->pTnsParameters[iFilter].startLineFrequency < 0.5f * nSampleRate );
178 93602 : assert( nSampleRate <= 96000 );
179 93602 : move16();
180 93602 : startLineFilter[iFilter] = divide3232( L_mult0( frameLength, pTnsConfig->pTnsParameters[iFilter].startLineFrequency ), L_shl( nSampleRate, 14 ) );
181 : }
182 :
183 51068 : IF( igfStopFreq > 0 )
184 : {
185 38363 : L_tmp = L_mult( frameLength, igfStopFreq );
186 38363 : s1 = sub( norm_l( L_tmp ), 1 );
187 38363 : s2 = norm_l( nSampleRate );
188 :
189 38363 : move16();
190 38363 : 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 12705 : move16();
195 12705 : pTnsConfig->iFilterBorders[0] = frameLength;
196 : }
197 51068 : return; /*TNS_NO_ERROR;*/
198 : }
199 :
200 0 : 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 0 : Word16 iFilter = 0;
210 0 : move16();
211 : Word16 *startLineFilter;
212 : Word32 L_tmp;
213 : Word32 nSampleRate;
214 : Word16 s1;
215 : Word16 s2;
216 :
217 0 : nSampleRate = bwMode2fs[bwidth];
218 0 : move32();
219 0 : startLineFilter = &pTnsConfig->iFilterBorders[1]; /*Q0*/
220 :
221 : /* Sanity checks */
222 0 : assert( ( nSampleRate > 0 ) && ( frameLength > 0 ) && ( pTnsConfig != NULL ) );
223 0 : test();
224 0 : test();
225 0 : 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 0 : move16();
233 0 : pTnsConfig->maxOrder = TNS_MAX_FILTER_ORDER;
234 :
235 0 : IF( LE_32( total_brate, ACELP_32k ) )
236 : {
237 0 : move16();
238 0 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParametersIGF32kHz_LowBR ), sizeof( tnsParametersIGF32kHz_LowBR[0] ) ); /*Q0*/
239 0 : pTnsConfig->pTnsParameters = tnsParametersIGF32kHz_LowBR;
240 : }
241 : ELSE
242 : {
243 0 : test();
244 0 : IF( GT_32( nSampleRate, 32000 ) && EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) )
245 : {
246 0 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters48kHz_grouped ), sizeof( tnsParameters48kHz_grouped[0] ) ); /*Q0*/
247 0 : move16();
248 0 : pTnsConfig->pTnsParameters = tnsParameters48kHz_grouped;
249 : }
250 0 : ELSE IF( GT_32( nSampleRate, INT_FS_16k ) )
251 : {
252 0 : L_tmp = IVAS_32k;
253 0 : move32();
254 0 : if ( !is_mct )
255 : {
256 0 : L_tmp = IVAS_48k;
257 0 : move32();
258 : }
259 0 : test();
260 0 : IF( GT_16( element_mode, IVAS_SCE ) && GE_32( total_brate, L_tmp ) )
261 : {
262 0 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters32kHz_Stereo ), sizeof( tnsParameters32kHz_Stereo[0] ) ); /*Q0*/
263 0 : move16();
264 0 : IF( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
265 : {
266 0 : pTnsConfig->pTnsParameters = tnsParameters32kHz_grouped;
267 : }
268 : ELSE
269 : {
270 0 : pTnsConfig->pTnsParameters = tnsParameters32kHz_Stereo;
271 : }
272 : }
273 : ELSE
274 : {
275 :
276 0 : move16();
277 0 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters32kHz ), sizeof( tnsParameters32kHz[0] ) ); /*Q0*/
278 :
279 0 : pTnsConfig->pTnsParameters = tnsParameters32kHz;
280 :
281 0 : if ( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
282 : {
283 0 : pTnsConfig->pTnsParameters = tnsParameters32kHz_grouped;
284 : }
285 : }
286 : }
287 : ELSE
288 : {
289 0 : IF( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
290 : {
291 0 : move16();
292 0 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters16kHz_grouped ), sizeof( tnsParameters16kHz_grouped[0] ) ); /*Q0*/
293 0 : pTnsConfig->pTnsParameters = tnsParameters16kHz_grouped;
294 : }
295 : ELSE
296 : {
297 0 : move16();
298 0 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters16kHz ), sizeof( tnsParameters16kHz[0] ) ); /*Q0*/
299 0 : pTnsConfig->pTnsParameters = tnsParameters16kHz;
300 : }
301 : }
302 : }
303 :
304 0 : 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 0 : FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
309 : {
310 0 : assert( pTnsConfig->pTnsParameters[iFilter].startLineFrequency < nSampleRate / 2 );
311 0 : assert( nSampleRate <= 96000 );
312 0 : move16();
313 0 : startLineFilter[iFilter] = divide3232( L_mult0( frameLength, pTnsConfig->pTnsParameters[iFilter].startLineFrequency ), L_shl( nSampleRate, 14 ) ); /*Q0*/
314 : }
315 :
316 0 : IF( igfStopFreq > 0 )
317 : {
318 0 : L_tmp = L_mult( frameLength, igfStopFreq );
319 0 : s1 = sub( norm_l( L_tmp ), 1 );
320 0 : s2 = norm_l( nSampleRate );
321 :
322 0 : move16();
323 0 : 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 0 : move16();
328 0 : pTnsConfig->iFilterBorders[0] = frameLength; /*Q0*/
329 : }
330 :
331 0 : pTnsConfig->allowTnsOnWhite = 0;
332 0 : move16();
333 :
334 0 : return; /*TNS_NO_ERROR;*/
335 : }
336 :
337 :
338 : /*-------------------------------------------------------------------*
339 : * ApplyTnsFilter()
340 : *
341 : *-------------------------------------------------------------------*/
342 :
343 86581 : 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 86581 : move16();
357 86581 : filter = IIRLattice;
358 86581 : if ( fIsAnalysis )
359 : {
360 0 : filter = FIRLattice;
361 : }
362 86581 : set32_fx( state, 0, TNS_MAX_FILTER_ORDER );
363 86581 : move16();
364 86581 : pBorders = pTnsConfig->iFilterBorders; /*Q0*/
365 :
366 258341 : FOR( iFilter = pTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
367 : {
368 : Word16 parCoeff[TNS_MAX_FILTER_ORDER];
369 : const STnsFilter *pFilter;
370 :
371 171760 : move16();
372 171760 : move16();
373 171760 : pFilter = &pTnsData->filter[iFilter];
374 171760 : stopLine = pBorders[iFilter];
375 171760 : startLine = pBorders[iFilter + 1];
376 :
377 171760 : Index2Parcor( pFilter->coefIndex, parCoeff, pFilter->order );
378 :
379 171760 : TnsFilter( &spectrum[startLine], stopLine - startLine,
380 171760 : parCoeff, pFilter->order,
381 : filter, state,
382 171760 : &spectrum[startLine] );
383 : }
384 :
385 86581 : move16();
386 :
387 86581 : return /*result*/;
388 : }
389 :
390 : /*-------------------------------------------------------------------*
391 : * ITF_Apply()
392 : *
393 : *-------------------------------------------------------------------*/
394 :
395 494193 : 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 494193 : ITF_TnsFilter_fx( &spectrum[startLine], sub( stopLine, startLine ), A, Q_A, order, &spectrum[startLine] );
405 :
406 494193 : return /*TNS_NO_ERROR*/;
407 : }
408 : /*-------------------------------------------------------------------*
409 : * ITF_Detect()
410 : *
411 : *
412 : *-------------------------------------------------------------------*/
413 :
414 538 : 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 538 : Word16 const nSubdivisions = MAX_SUBDIVISIONS;
428 538 : 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 538 : move16();
449 538 : move16();
450 538 : move16();
451 :
452 538 : if ( maxOrder <= 0 )
453 : {
454 0 : return 0;
455 : }
456 :
457 : /* Calculate norms for each spectrum part */
458 2152 : FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
459 : {
460 1614 : assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) );
461 :
462 1614 : tmp = sub( stopLine, startLine );
463 1614 : iStartLine = imult1616( tmp, iSubdivisions ); /*Q0*/
464 1614 : iEndLine = add( iStartLine, tmp );
465 :
466 1614 : if ( EQ_16( nSubdivisions, 3 ) )
467 1614 : iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/
468 1614 : iStartLine = add( iStartLine, startLine );
469 :
470 1614 : if ( EQ_16( nSubdivisions, 3 ) )
471 1614 : iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/
472 1614 : iEndLine = add( iEndLine, startLine );
473 1614 : headroom = getScaleFactor32( pSpectrum + iStartLine - IGF_START_MN, sub( iEndLine, iStartLine ) );
474 : /* Calculate norm of spectrum band */
475 1614 : 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 1614 : 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 1614 : tmp = sub( shift, norm_l( L_tmp ) ); /* exponent for normalized L_tmp */
488 1614 : tmp = shr( sub( 1, tmp ), 1 ); /* pre-shift to apply before autocorrelation */
489 1614 : shifts[iSubdivisions] = s_min( tmp, headroom );
490 1614 : move16();
491 :
492 : /* calc normalization factor */
493 1614 : facs[iSubdivisions] = 0;
494 1614 : move16();
495 1614 : facs_e[iSubdivisions] = 0;
496 1614 : move16();
497 :
498 1614 : if ( tmp32 > 0 )
499 : {
500 200 : facs[iSubdivisions] = 0x7FFF;
501 200 : move16(); /* normalization not needed for one subdivision */
502 : }
503 :
504 1614 : test();
505 1614 : IF( ( tmp32 > 0 ) && ( GT_16( nSubdivisions, 1 ) ) )
506 : {
507 200 : move16();
508 200 : facs_e[iSubdivisions] = shl( sub( tmp, shifts[iSubdivisions] ), 1 );
509 :
510 200 : tmp = sub( 1, shl( tmp, 1 ) ); /* exponent of autocorrelation */
511 200 : 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 200 : facs[iSubdivisions] = div_s( 0x2000, round_fx_sat( L_tmp ) ); /* L_tmp is >= 0x2000000 Q15*/
515 200 : move16();
516 : }
517 : }
518 :
519 : /* Calculate normalized autocorrelation for spectrum subdivision and get filter parameters based on it */
520 538 : set32_fx( rxx, 0, ITF_MAX_FILTER_ORDER + 1 );
521 :
522 538 : spectrumLength = sub( stopLine, startLine );
523 :
524 737 : FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
525 : {
526 715 : IF( facs[iSubdivisions] == 0 )
527 : {
528 516 : BREAK;
529 : }
530 :
531 :
532 199 : assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) );
533 :
534 199 : iStartLine = imult1616( spectrumLength, iSubdivisions ); /*Q0*/
535 199 : iEndLine = add( iStartLine, spectrumLength ); /*Q0*/
536 :
537 199 : if ( EQ_16( nSubdivisions, 3 ) )
538 199 : iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/
539 199 : iStartLine = add( iStartLine, startLine );
540 :
541 199 : if ( EQ_16( nSubdivisions, 3 ) )
542 199 : iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/
543 199 : iEndLine = add( iEndLine, startLine );
544 :
545 :
546 199 : move16();
547 199 : shift = shifts[iSubdivisions];
548 :
549 199 : n = sub( iEndLine, iStartLine );
550 199 : assert( n < (Word16) ( sizeof( tmpbuf ) / sizeof( Word16 ) ) );
551 24091 : FOR( i = 0; i < n; i++ )
552 : {
553 23892 : tmpbuf[i] = round_fx_sat( L_shl_sat( pSpectrum[iStartLine + i - IGF_START_MN], shift ) ); /*Q + shift - 16*/
554 23892 : move16();
555 : }
556 :
557 1990 : FOR( lag = 0; lag <= maxOrder; lag++ )
558 : {
559 1791 : n = sub( sub( iEndLine, lag ), iStartLine );
560 :
561 : {
562 1791 : Word64 tmp64 = 0;
563 209655 : FOR( i = 0; i < n; i++ )
564 : {
565 207864 : tmp64 = W_mac0_16_16( tmp64, tmpbuf[i], tmpbuf[i + lag] ); /*2*(Q + shift) - 32*/
566 : }
567 1791 : L_tmp = W_sat_l( tmp64 ); /*2*(Q + shift) - 32*/
568 : }
569 :
570 1791 : L_tmp = Mpy_32_16_1( L_tmp, facs[iSubdivisions] ); /*2*(Q + shift) - 32*/
571 1791 : L_tmp = L_shl( L_tmp, facs_e[iSubdivisions] ); /*2*(Q + shift) - 32 + facs_e*/
572 :
573 1791 : rxx[lag] = L_add( rxx[lag], L_tmp );
574 1791 : move32();
575 : }
576 : }
577 :
578 538 : IF( EQ_16( iSubdivisions, nSubdivisions ) ) /* meaning there is no subdivision with low energy */
579 : {
580 : /* Limit the maximum order to spectrum length/4 */
581 22 : ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain );
582 :
583 22 : *curr_order = maxOrder; /*Q0*/
584 22 : move16();
585 : }
586 :
587 538 : return 1;
588 : }
589 :
590 493655 : 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 493655 : IF( maxOrder <= 0 )
616 : {
617 0 : return 0;
618 : }
619 493655 : pWindow = tnsAcfWindow_fx;
620 493655 : set_zero_fx( norms, MAX_SUBDIVISIONS );
621 493655 : set_zero_fx( rxx, ITF_MAX_FILTER_ORDER + 1 ); /* This initialization is required */
622 493655 : set16_fx( q_rxx, Q31, ITF_MAX_FILTER_ORDER + 1 ); /* This initialization is required */
623 :
624 493655 : spectrumLength = sub( stopLine, startLine );
625 493655 : num_subdivisions = 0;
626 493655 : move16();
627 :
628 : /* Calculate norms for each spectrum part */
629 767627 : FOR( iSubdivisions = 0; iSubdivisions < MAX_SUBDIVISIONS; iSubdivisions++ )
630 : {
631 : /* iStartLine = startLine + ( stopLine - startLine ) * iSubdivisions / nSubdivisions; */
632 700472 : iStartLine = add( startLine, mult( imult1616( spectrumLength, iSubdivisions ), 10923 /* 1/MAX_SUBDIVISIONS in Q15 */ ) ); /*Q0*/
633 : /* iEndLine = startLine + ( stopLine - startLine ) * ( iSubdivisions + 1 ) / nSubdivisions; */
634 700472 : 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 700472 : ptr_spectrum1 = pSpectrum + sub( iStartLine, IGF_START_MN );
641 700472 : length = sub( iEndLine, iStartLine );
642 700472 : headroom = L_norm_arr( ptr_spectrum1, length );
643 700472 : guard_bits = find_guarded_bits_fx( length );
644 700472 : shift = sub( headroom, guard_bits );
645 :
646 700472 : Copy_Scale_sig32( ptr_spectrum1, temp_spectrum, length, shift ); // Q -> Q+shift
647 :
648 700472 : sum = 0;
649 700472 : move64();
650 72346944 : FOR( i = 0; i < length; i++ )
651 : {
652 71646472 : sum = W_mac_32_32( sum, temp_spectrum[i], temp_spectrum[i] ); // 2(Q+shift)+1
653 : }
654 : #ifdef FIX_ISSUE_1811_EXCEEDING_W_SHIFTS
655 700472 : IF( LE_64( sum, W_shl( 32768 * 2 /* HLM_MIN_NRG in Q1 */, s_min( 63, shl( add( Q, shift ), 1 ) ) ) ) )
656 : #else
657 : IF( LE_64( sum, W_shl( 32768 * 2 /* HLM_MIN_NRG in Q1 */, shl( add( Q, shift ), 1 ) ) ) )
658 : #endif
659 : {
660 426500 : BREAK;
661 : }
662 :
663 : /* fac = 1.0f / norms[iSubdivisions]; */
664 273972 : exp = W_norm( sum );
665 273972 : sum = W_shl( sum, exp ); // 2(Q+shift)+1+exp
666 273972 : 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)
667 273972 : q_fac = sub( 76, add( shl( add( Q, shift ), 1 ), exp ) );
668 273972 : pWindow = tnsAcfWindow_fx;
669 :
670 : /* For additional loop condition */
671 : /* Variable initialization */
672 : /*for ( lag = 1; lag <= maxOrder; lag++ )
673 : {
674 : rxx[lag] += fac * ( *pWindow ) * dotp( pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag );
675 : pWindow++;
676 : }*/
677 :
678 273972 : ptr_spectrum1 = temp_spectrum; // pSpectrum + iStartLine - IGF_START_MN;
679 2465748 : FOR( lag = 1; lag <= maxOrder; lag++ )
680 : {
681 : /* dotp( pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag ) */
682 2191776 : ptr_spectrum2 = temp_spectrum + lag; // pSpectrum + iStartLine - IGF_START_MN + lag;
683 :
684 2191776 : sum = 0;
685 2191776 : move64();
686 238216968 : FOR( i = 0; i < iEndLine - iStartLine - lag; i++ )
687 : {
688 236025192 : sum = W_mac_32_32( sum, ptr_spectrum1[i], ptr_spectrum2[i] ); // 2(Q+shift)+1
689 : }
690 2191776 : exp = W_norm( sum );
691 2191776 : sum = W_shl( sum, exp ); // 2(Q+shift)+1+exp
692 2191776 : 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
693 2191776 : q_temp = sub( add( q_fac, add( shl( add( Q, shift ), 1 ), exp ) ), 47 );
694 :
695 : /* rxx[lag] += fac * (*pWindow) * dotp(pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag); */
696 2191776 : q_min = sub( s_min( q_temp, q_rxx[lag] ), 1 );
697 2191776 : rxx[lag] = L_add( L_shl( rxx[lag], sub( q_min, q_rxx[lag] ) ), L_shl( temp, sub( q_min, q_temp ) ) );
698 2191776 : q_rxx[lag] = q_min;
699 2191776 : move32();
700 2191776 : move16();
701 :
702 2191776 : pWindow++;
703 : }
704 :
705 273972 : num_subdivisions = add( num_subdivisions, 1 );
706 : }
707 :
708 493655 : minimum_s( q_rxx + 1, ITF_MAX_FILTER_ORDER, &q_min );
709 493655 : q_min = s_min( Q29, q_min );
710 :
711 7898480 : FOR( i = 1; i < ITF_MAX_FILTER_ORDER; i++ )
712 : {
713 7404825 : rxx[i] = L_shl( rxx[i], sub( q_min, q_rxx[i] ) );
714 7404825 : move32();
715 : }
716 :
717 493655 : IF( EQ_16( iSubdivisions, MAX_SUBDIVISIONS ) ) /* meaning there is no subdivision with low energy */
718 : {
719 67155 : rxx[0] = L_shl( MAX_SUBDIVISIONS, q_min );
720 67155 : move32();
721 :
722 : /* Limit the maximum order to spectrum length/4 */
723 67155 : ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain );
724 :
725 67155 : *curr_order = maxOrder; /*Q0*/
726 67155 : move16();
727 : }
728 :
729 493655 : return 1;
730 : }
731 : /* Helper functions for Hufmann table coding */
732 :
733 :
734 : /** Get number of bits from a Huffman table.
735 : * The table must be sorted by values.
736 : */
737 0 : static Word16 GetBitsFromTable( const Word16 value /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
738 : {
739 : (void) nSize;
740 0 : assert( ( value >= 0 ) && ( value < nSize ) && ( nSize >= 0 ) && ( nSize <= 256 ) );
741 :
742 0 : move16();
743 0 : cast16();
744 0 : return (Word16) codes[value].nBits; /*Q0*/
745 : }
746 :
747 : /** Get the code for a value from a Huffman table.
748 : * The table must be sorted by values.
749 : */
750 0 : static Word16 EncodeUsingTable( const Word16 value /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
751 : {
752 : (void) nSize;
753 0 : assert( ( value >= 0 ) && ( value < nSize ) && ( nSize >= 0 ) && ( nSize <= 256 ) );
754 :
755 0 : move16();
756 0 : return codes[value].code; /*Q0*/
757 : }
758 :
759 :
760 : /** Decode a value from a bitstream using a Huffman table. */
761 706956 : static Word16 DecodeUsingTable( Decoder_State *st, Word16 *pValue /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
762 : {
763 706956 : Word16 code = 0;
764 706956 : Word16 nBits = 0;
765 706956 : move16();
766 706956 : move16();
767 : Word16 valueIndex;
768 :
769 706956 : assert( ( nSize >= 0 ) && ( nSize <= 256 ) );
770 :
771 :
772 706956 : move16();
773 706956 : valueIndex = nSize;
774 :
775 :
776 2544125 : WHILE( valueIndex == nSize )
777 : {
778 1837169 : code = add( shl( code, 1 ), get_next_indice_fx( st, 1 ) ); /*Q0*/
779 1837169 : nBits = add( nBits, 1 );
780 1837169 : test();
781 1837169 : IF( GT_16( nBits, nSize ) || GT_16( nBits, 16 ) )
782 : {
783 0 : st->BER_detect = 1;
784 0 : move16();
785 0 : *pValue = 0;
786 0 : move16();
787 :
788 0 : return -1;
789 : }
790 :
791 23624450 : FOR( valueIndex = 0; valueIndex < nSize; valueIndex++ )
792 : {
793 :
794 22494237 : IF( s_and( (Word16) EQ_16( codes[valueIndex].nBits, nBits ), (Word16) EQ_16( codes[valueIndex].code, code ) ) )
795 : {
796 706956 : BREAK;
797 : }
798 : }
799 : }
800 706956 : IF( LT_16( valueIndex, nSize ) )
801 : {
802 706956 : *pValue = (Word16) codes[valueIndex].value; /*Q0*/
803 706956 : move16();
804 : }
805 : ELSE
806 : {
807 0 : st->BER_detect = 1;
808 0 : move16();
809 0 : *pValue = 0;
810 0 : move16();
811 0 : return -1;
812 : }
813 :
814 706956 : return nBits; /*Q0*/
815 : }
816 :
817 :
818 : /* TNS filter coefficients */
819 :
820 456267 : Word16 DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
821 : {
822 456267 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
823 456267 : return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes );
824 : }
825 :
826 133766 : Word16 DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
827 : {
828 133766 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
829 133766 : return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes );
830 : }
831 :
832 8312 : Word16 DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
833 : {
834 8312 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
835 8312 : return DecodeUsingTable( st, pValue, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes );
836 : }
837 :
838 :
839 : /* TNS filter order */
840 :
841 79152 : Word16 DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
842 : {
843 : (void) index;
844 79152 : return DecodeUsingTable( st, pValue, codesTnsOrderTCX20, nTnsOrderCodes );
845 : }
846 :
847 0 : Word16 GetTnsFilterOrderBitsSWBTCX10_flt( const Word16 value, const Word16 index )
848 : {
849 : (void) index;
850 0 : return GetBitsFromTable( value - 1, codesTnsOrderTCX10, nTnsOrderCodes );
851 : }
852 :
853 0 : Word16 EncodeTnsFilterOrderSWBTCX10_flt( const Word16 value, const Word16 index )
854 : {
855 : (void) index;
856 0 : return EncodeUsingTable( value - 1, codesTnsOrderTCX10, nTnsOrderCodes );
857 : }
858 :
859 28111 : Word16 DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
860 : {
861 : (void) index;
862 28111 : return DecodeUsingTable( st, pValue, codesTnsOrderTCX10, nTnsOrderCodes );
863 : }
864 :
865 :
866 0 : void const *GetTnsFilterCoeff( void const *p, const Word16 index /*Q0*/, Word16 *pValue /*Q0*/ )
867 : {
868 0 : *pValue = ( (Word16 const *) p )[index] + INDEX_SHIFT;
869 0 : move16();
870 0 : return NULL;
871 : }
872 :
873 613061 : void *SetTnsFilterCoeff( void *p, const Word16 index /*Q0*/, const Word16 value /*Q0*/ )
874 : {
875 613061 : ( (Word16 *) p )[index] = sub( value, INDEX_SHIFT );
876 613061 : move16();
877 613061 : return NULL;
878 : }
879 :
880 :
881 0 : Word16 GetSWBTCX20TnsFilterCoeffBits( const Word16 value, const Word16 index )
882 : {
883 0 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
884 :
885 0 : return GetBitsFromTable( value, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
886 : }
887 :
888 0 : Word16 EncodeSWBTCX20TnsFilterCoeff( const Word16 value, const Word16 index )
889 : {
890 0 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
891 :
892 0 : return EncodeUsingTable( value, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
893 : }
894 :
895 0 : Word16 DecodeSWBTCX20TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
896 : {
897 0 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
898 :
899 0 : return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
900 : }
901 :
902 0 : Word16 GetSWBTCX10TnsFilterCoeffBits( const Word16 value, const Word16 index )
903 : {
904 0 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
905 :
906 0 : return GetBitsFromTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
907 : }
908 :
909 0 : Word16 EncodeSWBTCX10TnsFilterCoeff( const Word16 value, const Word16 index )
910 : {
911 0 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
912 :
913 0 : return EncodeUsingTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
914 : }
915 :
916 0 : Word16 DecodeSWBTCX10TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
917 : {
918 0 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
919 :
920 0 : return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
921 : }
922 :
923 0 : Word16 GetWBTCX20TnsFilterCoeffBits( const Word16 value, const Word16 index )
924 : {
925 0 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
926 :
927 0 : return GetBitsFromTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
928 : }
929 :
930 0 : Word16 EncodeWBTCX20TnsFilterCoeff( const Word16 value, const Word16 index )
931 : {
932 0 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
933 :
934 0 : return EncodeUsingTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
935 : }
936 :
937 0 : Word16 DecodeWBTCX20TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
938 : {
939 0 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
940 :
941 0 : return DecodeUsingTable( st, pValue, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
942 : }
943 :
944 :
945 : /* TNS filter order */
946 :
947 0 : void const *GetTnsFilterOrder( void const *p, const Word16 index, Word16 *pValue )
948 : {
949 0 : move16();
950 0 : *pValue = ( (STnsFilter const *) p )[index].order; /*Q0*/
951 :
952 0 : move16();
953 0 : return ( (STnsFilter const *) p )[index].coefIndex; /*Q0*/
954 : }
955 :
956 111545 : void *SetTnsFilterOrder( void *p, const Word16 index, const Word16 value )
957 : {
958 111545 : move16();
959 111545 : ( (STnsFilter *) p )[index].order = value; /*Q0*/
960 :
961 111545 : move16();
962 111545 : return ( (STnsFilter *) p )[index].coefIndex; /*Q0*/
963 : }
964 :
965 0 : Word16 GetTnsFilterOrderBitsSWBTCX20( const Word16 value, const Word16 index )
966 : {
967 : (void) index;
968 :
969 0 : return GetBitsFromTable( sub( value, 1 ), codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
970 : }
971 :
972 0 : Word16 EncodeTnsFilterOrderSWBTCX20( const Word16 value, const Word16 index )
973 : {
974 : (void) index;
975 :
976 0 : return EncodeUsingTable( sub( value, 1 ), codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
977 : }
978 :
979 0 : Word16 DecodeTnsFilterOrderSWBTCX20( Decoder_State *st, const Word16 index, Word16 *pValue )
980 : {
981 : (void) index;
982 :
983 0 : return DecodeUsingTable( st, pValue, codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
984 : }
985 :
986 0 : Word16 GetTnsFilterOrderBitsSWBTCX10( const Word16 value, const Word16 index )
987 : {
988 : (void) index;
989 :
990 0 : return GetBitsFromTable( sub( value, 1 ), codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
991 : }
992 :
993 0 : Word16 EncodeTnsFilterOrderSWBTCX10( const Word16 value, const Word16 index )
994 : {
995 : (void) index;
996 :
997 0 : return EncodeUsingTable( sub( value, 1 ), codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
998 : }
999 :
1000 0 : Word16 DecodeTnsFilterOrderSWBTCX10( Decoder_State *st, const Word16 index, Word16 *pValue )
1001 : {
1002 : (void) index;
1003 :
1004 0 : return DecodeUsingTable( st, pValue, codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
1005 : }
1006 :
1007 0 : Word16 GetTnsFilterOrderBits( const Word16 value, const Word16 index )
1008 : {
1009 : (void) index;
1010 :
1011 0 : return GetBitsFromTable( sub( value, 1 ), codesTnsOrder, nTnsOrderCodes ); /*Q0*/
1012 : }
1013 :
1014 0 : Word16 EncodeTnsFilterOrder( const Word16 value, const Word16 index )
1015 : {
1016 : (void) index;
1017 :
1018 0 : return EncodeUsingTable( sub( value, 1 ), codesTnsOrder, nTnsOrderCodes ); /*Q0*/
1019 : }
1020 :
1021 0 : Word16 DecodeTnsFilterOrder( Decoder_State *st, const Word16 index, Word16 *pValue )
1022 : {
1023 : (void) index;
1024 :
1025 0 : return DecodeUsingTable( st, pValue, codesTnsOrder, nTnsOrderCodes ); /*Q0*/
1026 : }
1027 :
1028 : /* Number of TNS filters */
1029 :
1030 0 : void const *GetNumOfTnsFilters( void const *p, const Word16 index, Word16 *pValue )
1031 : {
1032 0 : move16();
1033 0 : *pValue = ( (STnsData const *) p )[index].nFilters; /*Q0*/
1034 0 : move16();
1035 0 : return ( (STnsData const *) p )[index].filter;
1036 : }
1037 :
1038 0 : void *SetNumOfTnsFilters( void *p, const Word16 index, Word16 value )
1039 : {
1040 0 : move16();
1041 0 : ( (STnsData *) p )[index].nFilters = value; /*Q0*/
1042 0 : move16();
1043 0 : return ( (STnsData *) p )[index].filter;
1044 : }
1045 :
1046 : /* TNS enabled/disabled flag */
1047 :
1048 0 : void const *GetTnsEnabled( void const *p, const Word16 index, Word16 *pValue )
1049 : {
1050 0 : move16();
1051 0 : *pValue = 0;
1052 0 : if ( ( (STnsData const *) p )[index].nFilters != 0 )
1053 : {
1054 0 : move16();
1055 0 : *pValue = 1;
1056 : }
1057 0 : return NULL;
1058 : }
1059 :
1060 676111 : void *SetTnsEnabled( void *p, const Word16 index, const Word16 value )
1061 : {
1062 : (void) p, (void) index, (void) value;
1063 676111 : return NULL;
1064 : }
1065 :
1066 : /* Number of TNS filters */
1067 :
1068 0 : void const *GetNumOfTnsFilters_flt( void const *p, const Word16 index, Word16 *pValue )
1069 : {
1070 0 : *pValue = (Word16) abs( ( (STnsData const *) p )[index].nFilters );
1071 0 : return ( (STnsData const *) p )[index].filter;
1072 : }
1073 :
1074 85458 : void *SetNumOfTnsFilters_flt( void *p, const Word16 index, const Word16 value )
1075 : {
1076 85458 : ( (STnsData *) p )[index].nFilters = (Word16) abs( value );
1077 85458 : return ( (STnsData *) p )[index].filter;
1078 : }
1079 1348 : Word16 DecodeTnsFilterOrder_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
1080 : {
1081 : (void) index;
1082 1348 : return DecodeUsingTable( st, pValue, codesTnsOrder, nTnsOrderCodes );
1083 : }
1084 : /* TNS on whitened spectra flag */
1085 :
1086 0 : void const *GetTnsOnWhite( void const *p, const Word16 index, Word16 *pValue )
1087 : {
1088 0 : *pValue = ( (STnsData const *) p )[index].tnsOnWhitenedSpectra > 0 ? 1 : 0;
1089 0 : return NULL;
1090 : }
1091 :
1092 69178 : void *SetTnsOnWhite( void *p, const Word16 index, const Word16 value )
1093 : {
1094 69178 : ( (STnsData *) p )[index].tnsOnWhitenedSpectra = value;
1095 69178 : return NULL;
1096 : }
1097 :
1098 0 : void const *GetTnsEnabledSingleFilter( void const *p, const Word16 index, Word16 *pValue )
1099 : {
1100 0 : move16();
1101 0 : *pValue = 0;
1102 0 : if ( ( (STnsData const *) p )[index].nFilters > 0 )
1103 : {
1104 0 : move16();
1105 0 : *pValue = 1;
1106 : }
1107 0 : return ( (STnsData const *) p )[index].filter;
1108 : }
1109 :
1110 99835 : void *SetTnsEnabledSingleFilter( void *p, const Word16 index, const Word16 value )
1111 : {
1112 99835 : ( (STnsData *) p )[index].nFilters = value; /*Q0*/
1113 99835 : move16();
1114 99835 : return ( (STnsData *) p )[index].filter;
1115 : }
1116 :
1117 : /*-------------------------------------------------------------------*
1118 : * ResetTnsData()
1119 : *
1120 : *-------------------------------------------------------------------*/
1121 :
1122 775946 : void ResetTnsData( STnsData *pTnsData )
1123 : {
1124 : Word16 iFilter;
1125 :
1126 :
1127 775946 : pTnsData->nFilters = 0;
1128 775946 : move16();
1129 775946 : pTnsData->tnsOnWhitenedSpectra = 0;
1130 775946 : move16();
1131 2327838 : FOR( iFilter = 0; iFilter < (Word16) ( sizeof( pTnsData->filter ) / sizeof( pTnsData->filter[0] ) ); iFilter++ )
1132 : {
1133 1551892 : STnsFilter *const pTnsFilter = &pTnsData->filter[iFilter];
1134 1551892 : pTnsFilter->spectrumLength = 0;
1135 1551892 : move16();
1136 1551892 : pTnsFilter->predictionGain = ONE_IN_Q7; /*Q7*/
1137 1551892 : move16();
1138 1551892 : pTnsFilter->predictionGain32 = ONE_IN_Q23; /*Q23*/
1139 1551892 : move32();
1140 1551892 : pTnsFilter->predictionGain_e = PRED_GAIN_E;
1141 1551892 : move16();
1142 1551892 : pTnsFilter->avgSqrCoef = 0;
1143 1551892 : move16();
1144 1551892 : pTnsFilter->filterType = TNS_FILTER_OFF; /*Q0*/
1145 1551892 : move16();
1146 1551892 : ClearTnsFilterCoefficients( pTnsFilter );
1147 : }
1148 775946 : }
1149 : /*-------------------------------------------------------------------*
1150 : * ClearTnsFilterCoefficients()
1151 : *
1152 : *-------------------------------------------------------------------*/
1153 :
1154 1551892 : void ClearTnsFilterCoefficients(
1155 : STnsFilter *pTnsFilter )
1156 : {
1157 1551892 : move16();
1158 1551892 : pTnsFilter->order = 0;
1159 1551892 : move16();
1160 : assert( TNS_MAX_FILTER_ORDER == 8 );
1161 1551892 : move16();
1162 1551892 : move16();
1163 1551892 : move16();
1164 1551892 : move16();
1165 1551892 : move16();
1166 1551892 : move16();
1167 1551892 : move16();
1168 1551892 : move16();
1169 1551892 : pTnsFilter->coefIndex[0] = 0;
1170 1551892 : pTnsFilter->coefIndex[1] = 0;
1171 1551892 : pTnsFilter->coefIndex[2] = 0;
1172 1551892 : pTnsFilter->coefIndex[3] = 0;
1173 1551892 : pTnsFilter->coefIndex[4] = 0;
1174 1551892 : pTnsFilter->coefIndex[5] = 0;
1175 1551892 : pTnsFilter->coefIndex[6] = 0;
1176 1551892 : pTnsFilter->coefIndex[7] = 0;
1177 1551892 : }
1178 :
1179 : /** Inverse quantization for reflection coefficients.
1180 : *
1181 : * @param index input quantized values.
1182 : * @param parCoeff output reflection coefficients.
1183 : * @param order number of coefficients/values.
1184 : */
1185 171760 : static void Index2Parcor( const Word16 index[] /*Q0*/, Word16 parCoeff[] /*Q15*/, Word16 order /*Q0*/ )
1186 : {
1187 : const Word16 *values;
1188 : Word16 i;
1189 :
1190 171760 : move16();
1191 171760 : values = tnsCoeff4; /*Q15*/
1192 :
1193 782881 : FOR( i = 0; i < order; i++ )
1194 : {
1195 611121 : move16();
1196 611121 : parCoeff[i] = values[( index[i] + INDEX_SHIFT )]; /*Q15*/
1197 : }
1198 171760 : return;
1199 : }
1200 :
1201 :
1202 : /* Linear prediction analysis filter. */
1203 0 : static Word32 FIRLattice(
1204 : const Word16 order, /*Q0*/
1205 : const Word16 *parCoeff /*Q15*/,
1206 : Word32 *state, /*Q0*/
1207 : Word32 x /* Q0 */
1208 : )
1209 : {
1210 : Word16 i;
1211 : Word32 tmpSave, tmp;
1212 :
1213 :
1214 0 : tmpSave = x;
1215 0 : move32();
1216 0 : FOR( i = 0; i < order - 1; i++ )
1217 : {
1218 0 : tmp = Madd_32_16( state[i], x, parCoeff[i] ); /*Q0*/
1219 0 : x = Madd_32_16( x, state[i], parCoeff[i] ); /* exponent: 31+0 */
1220 0 : state[i] = tmpSave; /*Q0*/
1221 0 : move32();
1222 0 : tmpSave = tmp; /*Q0*/
1223 0 : move32();
1224 : }
1225 :
1226 : /* last stage: only need half operations */
1227 0 : x = Madd_32_16( x, state[order - 1], parCoeff[order - 1] ); /*Q0*/
1228 0 : state[order - 1] = tmpSave; /*Q0*/
1229 0 : move32();
1230 :
1231 0 : return x; /*Q0*/
1232 : }
1233 :
1234 49264478 : static Word32 IIRLattice( Word16 order /*Q0*/, const Word16 *parCoeff /*Q15*/, Word32 *state /*Q0*/, Word32 x /*Q0*/ )
1235 : {
1236 : Word16 i;
1237 :
1238 :
1239 : /* first stage: no need to calculate state[order-1] */
1240 49264478 : x = Msub_32_16( x, state[order - 1], parCoeff[order - 1] ); /*Q0*/
1241 :
1242 274105782 : FOR( i = order - 2; i >= 0; i-- )
1243 : {
1244 224841304 : x = Msub_32_16( x, state[i], parCoeff[i] ); /*Q0*/
1245 224841304 : state[i + 1] = Madd_32_16( state[i], x, parCoeff[i] ); /*Q0*/
1246 224841304 : move32();
1247 : }
1248 :
1249 49264478 : move32();
1250 49264478 : state[0] = x; /*Q0*/
1251 49264478 : return x; /*Q0*/
1252 : }
1253 : /** TNS analysis/synthesis filter.
1254 : * @param spectrum input spectrum values.
1255 : * @param numOfLines number of lines in the spectrum.
1256 : * @param parCoeff filter (PARCOR) coefficients.
1257 : * @param order filter order.
1258 : * @param filter function that implements filtering.
1259 : By this function it is defined whether analysis or synthesis is performed.
1260 : * @param output filtered output spectrum values.
1261 : Inplace operation is supported, so it can be equal to spectrum.
1262 : */
1263 171760 : static void TnsFilter(
1264 : const Word32 spectrum[], /*Qx*/
1265 : const Word16 numOfLines, /*Q0*/
1266 : const Word16 parCoeff[], /*Q15*/
1267 : const Word16 order, /*Q0*/
1268 : TLinearPredictionFilter filter,
1269 : Word32 *state, /*Q0*/
1270 : Word32 output[] /*Qx*/ )
1271 : {
1272 : Word16 j;
1273 :
1274 :
1275 171760 : assert( ( order >= 0 ) && ( order <= TNS_MAX_FILTER_ORDER ) );
1276 171760 : assert( ( numOfLines > 0 ) || ( ( numOfLines == 0 ) && ( order == 0 ) ) );
1277 :
1278 171760 : IF( order == 0 )
1279 : {
1280 :
1281 60582 : test();
1282 60582 : IF( s_and( ( spectrum != output ), numOfLines > 0 ) )
1283 : {
1284 0 : Copy32( spectrum, output, numOfLines ); /*Qx*/
1285 : }
1286 : }
1287 : ELSE
1288 : {
1289 : {
1290 :
1291 49375656 : FOR( j = 0; j < numOfLines; j++ )
1292 : {
1293 49264478 : move32();
1294 49264478 : output[j] = filter( order, parCoeff, state, spectrum[j] ); /*Qx*/
1295 : }
1296 : }
1297 : }
1298 171760 : return;
1299 : }
1300 :
1301 494193 : static void ITF_TnsFilter_fx(
1302 : const Word32 spectrum[], /*Qx*/
1303 : const Word16 numOfLines, /*Q0*/
1304 : const Word16 A[], /* ifdef FIX_ITF_OVERFLOW Q_A else Q14 */
1305 : const Word16 Q_A,
1306 : const Word16 order, /*Q0*/
1307 : Word32 output[] /*Qx*/ )
1308 : {
1309 : Word16 i, j;
1310 : Word32 buf[ITF_MAX_FILTER_ORDER + N_MAX];
1311 : Word32 *p;
1312 : Word16 shift;
1313 494193 : assert( ( order >= 0 ) && ( order <= ITF_MAX_FILTER_ORDER ) );
1314 494193 : assert( ( numOfLines > 0 ) || ( ( numOfLines == 0 ) && ( order == 0 ) ) );
1315 :
1316 494193 : IF( order == 0 )
1317 : {
1318 :
1319 427016 : test();
1320 427016 : IF( s_and( ( spectrum != output ), numOfLines > 0 ) )
1321 : {
1322 0 : Copy32( spectrum, output, numOfLines ); /*Qx*/
1323 : }
1324 : }
1325 : ELSE
1326 : {
1327 67177 : shift = sub( 15, Q_A );
1328 :
1329 67177 : p = buf + ITF_MAX_FILTER_ORDER;
1330 67177 : set32_fx( buf, 0, ITF_MAX_FILTER_ORDER );
1331 67177 : Copy32( spectrum, p, numOfLines ); /*Qx*/
1332 22122961 : FOR( j = 0; j < numOfLines; j++ )
1333 : {
1334 : Word32 L_tmp;
1335 :
1336 22055784 : L_tmp = L_add( p[0], 0 );
1337 176446272 : FOR( i = 1; i < order; i++ )
1338 : {
1339 154390488 : L_tmp = L_add_sat( L_tmp, L_shl( Mpy_32_16_1( p[-i], A[i] ), shift ) ); /*Qx*/
1340 : }
1341 22055784 : output[j] = L_tmp; /*Qx*/
1342 22055784 : move32();
1343 22055784 : ++p;
1344 : }
1345 : }
1346 494193 : return;
1347 : }
1348 :
1349 67177 : static void ITF_GetFilterParameters_fx(
1350 : Word32 rxx[], /*Qx*/
1351 : const Word16 maxOrder, /*Q0*/
1352 : Word16 *A, /* ifdef FIX_ITF_OVERFLOW Q_A else Q14 */
1353 : Word16 *Q_A,
1354 : Word16 *predictionGain /*Q7*/ )
1355 : {
1356 : Word16 i, j, i_2, tmp;
1357 : Word16 parCoeff[ITF_MAX_FILTER_ORDER];
1358 : Word32 epsP[ITF_MAX_FILTER_ORDER + 1], L_tmp;
1359 :
1360 : /* compute filter in ParCor form with LeRoux-Gueguen algorithm */
1361 67177 : L_tmp = E_LPC_schur( rxx, parCoeff, epsP, maxOrder );
1362 : BASOP_SATURATE_WARNING_OFF_EVS /* Allow saturation, this value is compared against a threshold. */
1363 67177 : *predictionGain = divide3232( L_shr( epsP[0], PRED_GAIN_E ), L_tmp ); /*Q7*/
1364 67177 : move16();
1365 : BASOP_SATURATE_WARNING_ON_EVS
1366 :
1367 : {
1368 : Word32 A32[ITF_MAX_FILTER_ORDER];
1369 : Word16 tmp1_l, tmp1_h, tmp2_l, tmp2_h;
1370 :
1371 : /* Convert ParCor / reflection coefficients to LPC */
1372 67177 : A32[0] = 134217728l /*1.0 Q27*/;
1373 67177 : move32(); /* Q11+16 */
1374 67177 : A32[1] = L_shr( L_deposit_h( parCoeff[0] ), 4 ); /* Q11+16 */
1375 67177 : move32();
1376 :
1377 537416 : FOR( i = 1; i < maxOrder; i++ )
1378 : {
1379 470239 : L_tmp = L_shr( L_deposit_h( parCoeff[i] ), 3 ); /* Q11+16 */
1380 :
1381 470239 : i_2 = shr( i, 1 );
1382 1276363 : FOR( j = 0; j < i_2; j++ )
1383 : {
1384 806124 : tmp1_l = L_Extract_lc( A32[i - 1 - j + 1], &tmp1_h );
1385 806124 : tmp2_l = L_Extract_lc( A32[j + 1], &tmp2_h );
1386 806124 : A32[j + 1] = Mac_32( A32[j + 1], parCoeff[i], 0, tmp1_h, tmp1_l ); /*+= parCoeff[i] * a[i-1-j+1]; Q11+16*/
1387 806124 : move32();
1388 806124 : A32[i - 1 - j + 1] = Mac_32( A32[i - 1 - j + 1], parCoeff[i], 0, tmp2_h, tmp2_l ); /*+= parCoeff[i] * tmp; Q11+16*/
1389 806124 : move32();
1390 : }
1391 470239 : IF( s_and( i, 1 ) )
1392 : {
1393 268708 : tmp2_l = L_Extract_lc( A32[j + 1], &tmp2_h );
1394 268708 : A32[j + 1] = Mac_32( A32[j + 1], parCoeff[i], 0, tmp2_h, tmp2_l ); /*+= parCoeff[i] * a[j+1]; Q11+16*/
1395 268708 : move32();
1396 : }
1397 :
1398 470239 : A32[i + 1] = L_shr( L_deposit_h( parCoeff[i] ), 4 ); /* Q11+16 */
1399 470239 : move32();
1400 : }
1401 :
1402 67177 : tmp = 3;
1403 67177 : move16(); /* assume Q11 -> Q14 */
1404 604593 : FOR( i = 0; i < maxOrder; i++ )
1405 : {
1406 537416 : tmp = s_min( tmp, norm_l( A32[i] ) );
1407 : }
1408 604593 : FOR( i = 0; i < maxOrder; i++ )
1409 : {
1410 537416 : A[i] = round_fx( L_shl( A32[i], tmp ) ); /* Q11+tmp */
1411 537416 : move16();
1412 : }
1413 67177 : *Q_A = add( 11, tmp );
1414 67177 : move16();
1415 : }
1416 67177 : return;
1417 : }
|