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