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