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 45392 : 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 45392 : Word16 iFilter = 0;
93 45392 : 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 45392 : nSampleRate = bwMode2fs[bwidth];
102 45392 : move32();
103 45392 : startLineFilter = &pTnsConfig->iFilterBorders[1];
104 :
105 : /* Sanity checks */
106 45392 : assert( ( nSampleRate > 0 ) && ( frameLength > 0 ) && ( pTnsConfig != NULL ) );
107 45392 : test();
108 45392 : test();
109 45392 : 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 45392 : move16();
117 45392 : pTnsConfig->maxOrder = TNS_MAX_FILTER_ORDER;
118 :
119 45392 : IF( LE_32( total_brate, ACELP_32k ) )
120 : {
121 6404 : move16();
122 6404 : move16();
123 6404 : pTnsConfig->nMaxFilters = sizeof( tnsParametersIGF32kHz_LowBR ) / sizeof( tnsParametersIGF32kHz_LowBR[0] );
124 6404 : 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 45392 : 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 128506 : FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
177 : {
178 83114 : assert( pTnsConfig->pTnsParameters[iFilter].startLineFrequency < 0.5f * nSampleRate );
179 83114 : assert( nSampleRate <= 96000 );
180 83114 : move16();
181 83114 : startLineFilter[iFilter] = divide3232( L_mult0( frameLength, pTnsConfig->pTnsParameters[iFilter].startLineFrequency ), L_shl( nSampleRate, 14 ) );
182 : }
183 :
184 45392 : IF( igfStopFreq > 0 )
185 : {
186 34442 : L_tmp = L_mult( frameLength, igfStopFreq );
187 34442 : s1 = sub( norm_l( L_tmp ), 1 );
188 34442 : s2 = norm_l( nSampleRate );
189 :
190 34442 : move16();
191 34442 : 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 45392 : return; /*TNS_NO_ERROR;*/
199 : }
200 :
201 82401 : 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 82401 : Word16 iFilter = 0;
211 82401 : move16();
212 : Word16 *startLineFilter;
213 : Word32 L_tmp;
214 : Word32 nSampleRate;
215 : Word16 s1;
216 : Word16 s2;
217 :
218 82401 : nSampleRate = bwMode2fs[bwidth];
219 82401 : move32();
220 82401 : startLineFilter = &pTnsConfig->iFilterBorders[1]; /*Q0*/
221 :
222 : /* Sanity checks */
223 82401 : assert( ( nSampleRate > 0 ) && ( frameLength > 0 ) && ( pTnsConfig != NULL ) );
224 82401 : test();
225 82401 : test();
226 82401 : 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 82401 : move16();
234 82401 : pTnsConfig->maxOrder = TNS_MAX_FILTER_ORDER;
235 :
236 82401 : IF( LE_32( total_brate, ACELP_32k ) )
237 : {
238 19836 : move16();
239 19836 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParametersIGF32kHz_LowBR ), sizeof( tnsParametersIGF32kHz_LowBR[0] ) ); /*Q0*/
240 19836 : pTnsConfig->pTnsParameters = tnsParametersIGF32kHz_LowBR;
241 : }
242 : ELSE
243 : {
244 62565 : test();
245 62565 : IF( GT_32( nSampleRate, 32000 ) && EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) )
246 : {
247 16043 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters48kHz_grouped ), sizeof( tnsParameters48kHz_grouped[0] ) ); /*Q0*/
248 16043 : move16();
249 16043 : pTnsConfig->pTnsParameters = tnsParameters48kHz_grouped;
250 : }
251 46522 : ELSE IF( GT_32( nSampleRate, INT_FS_16k ) )
252 : {
253 44251 : L_tmp = IVAS_32k;
254 44251 : move32();
255 44251 : if ( !is_mct )
256 : {
257 27893 : L_tmp = IVAS_48k;
258 27893 : move32();
259 : }
260 44251 : test();
261 44251 : IF( GT_16( element_mode, IVAS_SCE ) && GE_32( total_brate, L_tmp ) )
262 : {
263 34430 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters32kHz_Stereo ), sizeof( tnsParameters32kHz_Stereo[0] ) ); /*Q0*/
264 34430 : move16();
265 34430 : IF( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
266 : {
267 3678 : pTnsConfig->pTnsParameters = tnsParameters32kHz_grouped;
268 : }
269 : ELSE
270 : {
271 30752 : pTnsConfig->pTnsParameters = tnsParameters32kHz_Stereo;
272 : }
273 : }
274 : ELSE
275 : {
276 :
277 9821 : move16();
278 9821 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters32kHz ), sizeof( tnsParameters32kHz[0] ) ); /*Q0*/
279 :
280 9821 : pTnsConfig->pTnsParameters = tnsParameters32kHz;
281 :
282 9821 : if ( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
283 : {
284 377 : pTnsConfig->pTnsParameters = tnsParameters32kHz_grouped;
285 : }
286 : }
287 : }
288 : ELSE
289 : {
290 2271 : IF( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
291 : {
292 757 : move16();
293 757 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters16kHz_grouped ), sizeof( tnsParameters16kHz_grouped[0] ) ); /*Q0*/
294 757 : pTnsConfig->pTnsParameters = tnsParameters16kHz_grouped;
295 : }
296 : ELSE
297 : {
298 1514 : move16();
299 1514 : pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters16kHz ), sizeof( tnsParameters16kHz[0] ) ); /*Q0*/
300 1514 : pTnsConfig->pTnsParameters = tnsParameters16kHz;
301 : }
302 : }
303 : }
304 :
305 82401 : 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 225853 : FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
310 : {
311 143452 : assert( pTnsConfig->pTnsParameters[iFilter].startLineFrequency < nSampleRate / 2 );
312 143452 : assert( nSampleRate <= 96000 );
313 143452 : move16();
314 143452 : startLineFilter[iFilter] = divide3232( L_mult0( frameLength, pTnsConfig->pTnsParameters[iFilter].startLineFrequency ), L_shl( nSampleRate, 14 ) ); /*Q0*/
315 : }
316 :
317 82401 : IF( igfStopFreq > 0 )
318 : {
319 66534 : L_tmp = L_mult( frameLength, igfStopFreq );
320 66534 : s1 = sub( norm_l( L_tmp ), 1 );
321 66534 : s2 = norm_l( nSampleRate );
322 :
323 66534 : move16();
324 66534 : 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 15867 : move16();
329 15867 : pTnsConfig->iFilterBorders[0] = frameLength; /*Q0*/
330 : }
331 :
332 82401 : pTnsConfig->allowTnsOnWhite = 0;
333 82401 : move16();
334 :
335 82401 : return; /*TNS_NO_ERROR;*/
336 : }
337 :
338 :
339 : /*-------------------------------------------------------------------*
340 : * ApplyTnsFilter()
341 : *
342 : *-------------------------------------------------------------------*/
343 :
344 185583 : 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 185583 : move16();
358 185583 : filter = IIRLattice;
359 185583 : if ( fIsAnalysis )
360 : {
361 87239 : filter = FIRLattice;
362 : }
363 185583 : set32_fx( state, 0, TNS_MAX_FILTER_ORDER );
364 185583 : move16();
365 185583 : pBorders = pTnsConfig->iFilterBorders; /*Q0*/
366 :
367 553726 : FOR( iFilter = pTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
368 : {
369 : Word16 parCoeff[TNS_MAX_FILTER_ORDER];
370 : const STnsFilter *pFilter;
371 :
372 368143 : move16();
373 368143 : move16();
374 368143 : pFilter = &pTnsData->filter[iFilter];
375 368143 : stopLine = pBorders[iFilter];
376 368143 : startLine = pBorders[iFilter + 1];
377 :
378 368143 : Index2Parcor( pFilter->coefIndex, parCoeff, pFilter->order );
379 :
380 368143 : TnsFilter( &spectrum[startLine], stopLine - startLine,
381 368143 : parCoeff, pFilter->order,
382 : filter, state,
383 368143 : &spectrum[startLine] );
384 : }
385 :
386 185583 : move16();
387 :
388 185583 : 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 1171 : 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 1171 : Word16 const nSubdivisions = MAX_SUBDIVISIONS;
429 1171 : 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 1171 : Flag Overflow = 0;
444 1171 : move32();
445 : #endif
446 :
447 1171 : move16();
448 1171 : move16();
449 1171 : move16();
450 :
451 1171 : if ( maxOrder <= 0 )
452 : {
453 0 : return 0;
454 : }
455 :
456 : /* Calculate norms for each spectrum part */
457 4684 : FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
458 : {
459 3513 : assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) );
460 :
461 3513 : tmp = sub( stopLine, startLine );
462 3513 : iStartLine = imult1616( tmp, iSubdivisions ); /*Q0*/
463 3513 : iEndLine = add( iStartLine, tmp );
464 :
465 3513 : if ( EQ_16( nSubdivisions, 3 ) )
466 3513 : iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/
467 3513 : iStartLine = add( iStartLine, startLine );
468 :
469 3513 : if ( EQ_16( nSubdivisions, 3 ) )
470 3513 : iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/
471 3513 : iEndLine = add( iEndLine, startLine );
472 3513 : headroom = getScaleFactor32( pSpectrum + iStartLine - IGF_START_MN, sub( iEndLine, iStartLine ) );
473 : /* Calculate norm of spectrum band */
474 3513 : 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 3513 : 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 3513 : tmp = sub( shift, norm_l( L_tmp ) ); /* exponent for normalized L_tmp */
483 3513 : tmp = shr( sub( 1, tmp ), 1 ); /* pre-shift to apply before autocorrelation */
484 3513 : shifts[iSubdivisions] = s_min( tmp, headroom );
485 3513 : move16();
486 :
487 : /* calc normalization factor */
488 3513 : facs[iSubdivisions] = 0;
489 3513 : move16();
490 3513 : facs_e[iSubdivisions] = 0;
491 3513 : move16();
492 :
493 3513 : if ( tmp32 > 0 )
494 : {
495 688 : facs[iSubdivisions] = 0x7FFF;
496 688 : move16(); /* normalization not needed for one subdivision */
497 : }
498 :
499 3513 : test();
500 3513 : IF( ( tmp32 > 0 ) && ( GT_16( nSubdivisions, 1 ) ) )
501 : {
502 688 : move16();
503 688 : facs_e[iSubdivisions] = shl( sub( tmp, shifts[iSubdivisions] ), 1 );
504 :
505 688 : tmp = sub( 1, shl( tmp, 1 ) ); /* exponent of autocorrelation */
506 688 : 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 688 : facs[iSubdivisions] = div_s( 0x2000, round_fx_sat( L_tmp ) ); /* L_tmp is >= 0x2000000 Q15*/
510 688 : move16();
511 : }
512 : }
513 :
514 : /* Calculate normalized autocorrelation for spectrum subdivision and get filter parameters based on it */
515 1171 : set32_fx( rxx, 0, ITF_MAX_FILTER_ORDER + 1 );
516 :
517 1171 : spectrumLength = sub( stopLine, startLine );
518 :
519 1853 : FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
520 : {
521 1734 : IF( facs[iSubdivisions] == 0 )
522 : {
523 1052 : BREAK;
524 : }
525 :
526 :
527 682 : assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) );
528 :
529 682 : iStartLine = imult1616( spectrumLength, iSubdivisions ); /*Q0*/
530 682 : iEndLine = add( iStartLine, spectrumLength ); /*Q0*/
531 :
532 682 : if ( EQ_16( nSubdivisions, 3 ) )
533 682 : iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/
534 682 : iStartLine = add( iStartLine, startLine );
535 :
536 682 : if ( EQ_16( nSubdivisions, 3 ) )
537 682 : iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/
538 682 : iEndLine = add( iEndLine, startLine );
539 :
540 :
541 682 : move16();
542 682 : shift = shifts[iSubdivisions];
543 :
544 682 : n = sub( iEndLine, iStartLine );
545 682 : assert( n < (Word16) ( sizeof( tmpbuf ) / sizeof( Word16 ) ) );
546 81112 : FOR( i = 0; i < n; i++ )
547 : {
548 80430 : tmpbuf[i] = round_fx_sat( L_shl_sat( pSpectrum[iStartLine + i - IGF_START_MN], shift ) ); /*Q + shift - 16*/
549 80430 : move16();
550 : }
551 :
552 6820 : FOR( lag = 0; lag <= maxOrder; lag++ )
553 : {
554 6138 : n = sub( sub( iEndLine, lag ), iStartLine );
555 :
556 : {
557 6138 : Word64 tmp64 = 0;
558 705456 : FOR( i = 0; i < n; i++ )
559 : {
560 699318 : tmp64 = W_mac0_16_16( tmp64, tmpbuf[i], tmpbuf[i + lag] ); /*2*(Q + shift) - 32*/
561 : }
562 6138 : L_tmp = W_sat_l( tmp64 ); /*2*(Q + shift) - 32*/
563 : }
564 :
565 6138 : L_tmp = Mpy_32_16_1( L_tmp, facs[iSubdivisions] ); /*2*(Q + shift) - 32*/
566 6138 : L_tmp = L_shl( L_tmp, facs_e[iSubdivisions] ); /*2*(Q + shift) - 32 + facs_e*/
567 :
568 6138 : rxx[lag] = L_add( rxx[lag], L_tmp );
569 6138 : move32();
570 : }
571 : }
572 :
573 1171 : IF( EQ_16( iSubdivisions, nSubdivisions ) ) /* meaning there is no subdivision with low energy */
574 : {
575 : /* Limit the maximum order to spectrum length/4 */
576 119 : ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain );
577 :
578 119 : *curr_order = maxOrder; /*Q0*/
579 119 : move16();
580 : }
581 :
582 1171 : return 1;
583 : }
584 :
585 1057344 : 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 1057344 : IF( maxOrder <= 0 )
611 : {
612 0 : return 0;
613 : }
614 1057344 : pWindow = tnsAcfWindow_fx;
615 1057344 : set_zero_fx( norms, MAX_SUBDIVISIONS );
616 1057344 : set_zero_fx( rxx, ITF_MAX_FILTER_ORDER + 1 ); /* This initialization is required */
617 1057344 : set16_fx( q_rxx, Q31, ITF_MAX_FILTER_ORDER + 1 ); /* This initialization is required */
618 :
619 1057344 : spectrumLength = sub( stopLine, startLine );
620 1057344 : num_subdivisions = 0;
621 1057344 : move16();
622 :
623 : /* Calculate norms for each spectrum part */
624 1713940 : FOR( iSubdivisions = 0; iSubdivisions < MAX_SUBDIVISIONS; iSubdivisions++ )
625 : {
626 : /* iStartLine = startLine + ( stopLine - startLine ) * iSubdivisions / nSubdivisions; */
627 1551433 : iStartLine = add( startLine, mult( imult1616( spectrumLength, iSubdivisions ), 10923 /* 1/MAX_SUBDIVISIONS in Q15 */ ) ); /*Q0*/
628 : /* iEndLine = startLine + ( stopLine - startLine ) * ( iSubdivisions + 1 ) / nSubdivisions; */
629 1551433 : 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 1551433 : ptr_spectrum1 = pSpectrum + sub( iStartLine, IGF_START_MN );
636 1551433 : length = sub( iEndLine, iStartLine );
637 1551433 : headroom = L_norm_arr( ptr_spectrum1, length );
638 1551433 : guard_bits = find_guarded_bits_fx( length );
639 1551433 : shift = sub( headroom, guard_bits );
640 :
641 1551433 : Copy_Scale_sig32( ptr_spectrum1, temp_spectrum, length, shift ); // Q -> Q+shift
642 :
643 1551433 : sum = 0;
644 1551433 : move64();
645 159521619 : FOR( i = 0; i < length; i++ )
646 : {
647 157970186 : sum = W_mac_32_32( sum, temp_spectrum[i], temp_spectrum[i] ); // 2(Q+shift)+1
648 : }
649 :
650 1551433 : IF( LE_64( sum, W_shl( 32768 * 2 /* HLM_MIN_NRG in Q1 */, shl( add( Q, shift ), 1 ) ) ) )
651 : {
652 894837 : BREAK;
653 : }
654 :
655 : /* fac = 1.0f / norms[iSubdivisions]; */
656 656596 : exp = W_norm( sum );
657 656596 : sum = W_shl( sum, exp ); // 2(Q+shift)+1+exp
658 656596 : 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 656596 : q_fac = sub( 76, add( shl( add( Q, shift ), 1 ), exp ) );
660 656596 : 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 656596 : ptr_spectrum1 = temp_spectrum; // pSpectrum + iStartLine - IGF_START_MN;
671 5909364 : FOR( lag = 1; lag <= maxOrder; lag++ )
672 : {
673 : /* dotp( pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag ) */
674 5252768 : ptr_spectrum2 = temp_spectrum + lag; // pSpectrum + iStartLine - IGF_START_MN + lag;
675 :
676 5252768 : sum = 0;
677 5252768 : move64();
678 566869864 : FOR( i = 0; i < iEndLine - iStartLine - lag; i++ )
679 : {
680 561617096 : sum = W_mac_32_32( sum, ptr_spectrum1[i], ptr_spectrum2[i] ); // 2(Q+shift)+1
681 : }
682 5252768 : exp = W_norm( sum );
683 5252768 : sum = W_shl( sum, exp ); // 2(Q+shift)+1+exp
684 5252768 : 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 5252768 : 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 5252768 : q_min = sub( s_min( q_temp, q_rxx[lag] ), 1 );
689 5252768 : rxx[lag] = L_add( L_shl( rxx[lag], sub( q_min, q_rxx[lag] ) ), L_shl( temp, sub( q_min, q_temp ) ) );
690 5252768 : q_rxx[lag] = q_min;
691 5252768 : move32();
692 5252768 : move16();
693 :
694 5252768 : pWindow++;
695 : }
696 :
697 656596 : num_subdivisions = add( num_subdivisions, 1 );
698 : }
699 :
700 1057344 : minimum_s( q_rxx + 1, ITF_MAX_FILTER_ORDER, &q_min );
701 1057344 : q_min = s_min( Q29, q_min );
702 :
703 16917504 : FOR( i = 1; i < ITF_MAX_FILTER_ORDER; i++ )
704 : {
705 15860160 : rxx[i] = L_shl( rxx[i], sub( q_min, q_rxx[i] ) );
706 15860160 : move32();
707 : }
708 :
709 1057344 : IF( EQ_16( iSubdivisions, MAX_SUBDIVISIONS ) ) /* meaning there is no subdivision with low energy */
710 : {
711 162507 : rxx[0] = L_shl( MAX_SUBDIVISIONS, q_min );
712 162507 : move32();
713 :
714 : /* Limit the maximum order to spectrum length/4 */
715 162507 : ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain );
716 :
717 162507 : *curr_order = maxOrder; /*Q0*/
718 162507 : move16();
719 : }
720 :
721 1057344 : 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 1439459 : static Word16 GetBitsFromTable( const Word16 value /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
730 : {
731 : (void) nSize;
732 1439459 : assert( ( value >= 0 ) && ( value < nSize ) && ( nSize >= 0 ) && ( nSize <= 256 ) );
733 :
734 1439459 : move16();
735 1439459 : cast16();
736 1439459 : 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 711050 : static Word16 EncodeUsingTable( const Word16 value /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
743 : {
744 : (void) nSize;
745 711050 : assert( ( value >= 0 ) && ( value < nSize ) && ( nSize >= 0 ) && ( nSize <= 256 ) );
746 :
747 711050 : move16();
748 711050 : 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 : Word16 DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
813 : {
814 429272 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
815 429272 : return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes );
816 : }
817 :
818 121144 : Word16 DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
819 : {
820 121144 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
821 121144 : return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes );
822 : }
823 :
824 7562 : Word16 DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
825 : {
826 7562 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
827 7562 : return DecodeUsingTable( st, pValue, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes );
828 : }
829 :
830 :
831 : /* TNS filter order */
832 :
833 74575 : Word16 DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
834 : {
835 : (void) index;
836 74575 : return DecodeUsingTable( st, pValue, codesTnsOrderTCX20, nTnsOrderCodes );
837 : }
838 :
839 0 : Word16 GetTnsFilterOrderBitsSWBTCX10_flt( const Word16 value, const Word16 index )
840 : {
841 : (void) index;
842 0 : return GetBitsFromTable( value - 1, codesTnsOrderTCX10, nTnsOrderCodes );
843 : }
844 :
845 0 : Word16 EncodeTnsFilterOrderSWBTCX10_flt( const Word16 value, const Word16 index )
846 : {
847 : (void) index;
848 0 : return EncodeUsingTable( value - 1, codesTnsOrderTCX10, nTnsOrderCodes );
849 : }
850 :
851 25211 : Word16 DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
852 : {
853 : (void) index;
854 25211 : return DecodeUsingTable( st, pValue, codesTnsOrderTCX10, nTnsOrderCodes );
855 : }
856 :
857 :
858 616528 : void const *GetTnsFilterCoeff( void const *p, const Word16 index /*Q0*/, Word16 *pValue /*Q0*/ )
859 : {
860 616528 : *pValue = ( (Word16 const *) p )[index] + INDEX_SHIFT;
861 616528 : move16();
862 616528 : return NULL;
863 : }
864 :
865 571749 : void *SetTnsFilterCoeff( void *p, const Word16 index /*Q0*/, const Word16 value /*Q0*/ )
866 : {
867 571749 : ( (Word16 *) p )[index] = sub( value, INDEX_SHIFT );
868 571749 : move16();
869 571749 : return NULL;
870 : }
871 :
872 :
873 937499 : Word16 GetSWBTCX20TnsFilterCoeffBits( const Word16 value, const Word16 index )
874 : {
875 937499 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
876 :
877 937499 : return GetBitsFromTable( value, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
878 : }
879 :
880 463074 : Word16 EncodeSWBTCX20TnsFilterCoeff( const Word16 value, const Word16 index )
881 : {
882 463074 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
883 :
884 463074 : return EncodeUsingTable( value, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
885 : }
886 :
887 0 : Word16 DecodeSWBTCX20TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
888 : {
889 0 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
890 :
891 0 : return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
892 : }
893 :
894 264768 : Word16 GetSWBTCX10TnsFilterCoeffBits( const Word16 value, const Word16 index )
895 : {
896 264768 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
897 :
898 264768 : return GetBitsFromTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
899 : }
900 :
901 130839 : Word16 EncodeSWBTCX10TnsFilterCoeff( const Word16 value, const Word16 index )
902 : {
903 130839 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
904 :
905 130839 : return EncodeUsingTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
906 : }
907 :
908 0 : Word16 DecodeSWBTCX10TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
909 : {
910 0 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
911 :
912 0 : return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
913 : }
914 :
915 16308 : Word16 GetWBTCX20TnsFilterCoeffBits( const Word16 value, const Word16 index )
916 : {
917 16308 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
918 :
919 16308 : return GetBitsFromTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
920 : }
921 :
922 8134 : Word16 EncodeWBTCX20TnsFilterCoeff( const Word16 value, const Word16 index )
923 : {
924 8134 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
925 :
926 8134 : return EncodeUsingTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
927 : }
928 :
929 0 : Word16 DecodeWBTCX20TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
930 : {
931 0 : assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
932 :
933 0 : return DecodeUsingTable( st, pValue, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
934 : }
935 :
936 :
937 : /* TNS filter order */
938 :
939 111881 : void const *GetTnsFilterOrder( void const *p, const Word16 index, Word16 *pValue )
940 : {
941 111881 : move16();
942 111881 : *pValue = ( (STnsFilter const *) p )[index].order; /*Q0*/
943 :
944 111881 : move16();
945 111881 : return ( (STnsFilter const *) p )[index].coefIndex; /*Q0*/
946 : }
947 :
948 103770 : void *SetTnsFilterOrder( void *p, const Word16 index, const Word16 value )
949 : {
950 103770 : move16();
951 103770 : ( (STnsFilter *) p )[index].order = value; /*Q0*/
952 :
953 103770 : move16();
954 103770 : return ( (STnsFilter *) p )[index].coefIndex; /*Q0*/
955 : }
956 :
957 162945 : Word16 GetTnsFilterOrderBitsSWBTCX20( const Word16 value, const Word16 index )
958 : {
959 : (void) index;
960 :
961 162945 : return GetBitsFromTable( sub( value, 1 ), codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
962 : }
963 :
964 80425 : Word16 EncodeTnsFilterOrderSWBTCX20( const Word16 value, const Word16 index )
965 : {
966 : (void) index;
967 :
968 80425 : return EncodeUsingTable( sub( value, 1 ), codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
969 : }
970 :
971 0 : Word16 DecodeTnsFilterOrderSWBTCX20( Decoder_State *st, const Word16 index, Word16 *pValue )
972 : {
973 : (void) index;
974 :
975 0 : return DecodeUsingTable( st, pValue, codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
976 : }
977 :
978 55319 : Word16 GetTnsFilterOrderBitsSWBTCX10( const Word16 value, const Word16 index )
979 : {
980 : (void) index;
981 :
982 55319 : return GetBitsFromTable( sub( value, 1 ), codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
983 : }
984 :
985 27272 : Word16 EncodeTnsFilterOrderSWBTCX10( const Word16 value, const Word16 index )
986 : {
987 : (void) index;
988 :
989 27272 : return EncodeUsingTable( sub( value, 1 ), codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
990 : }
991 :
992 0 : Word16 DecodeTnsFilterOrderSWBTCX10( Decoder_State *st, const Word16 index, Word16 *pValue )
993 : {
994 : (void) index;
995 :
996 0 : return DecodeUsingTable( st, pValue, codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
997 : }
998 :
999 2620 : Word16 GetTnsFilterOrderBits( const Word16 value, const Word16 index )
1000 : {
1001 : (void) index;
1002 :
1003 2620 : return GetBitsFromTable( sub( value, 1 ), codesTnsOrder, nTnsOrderCodes ); /*Q0*/
1004 : }
1005 :
1006 1306 : Word16 EncodeTnsFilterOrder( const Word16 value, const Word16 index )
1007 : {
1008 : (void) index;
1009 :
1010 1306 : return EncodeUsingTable( sub( value, 1 ), codesTnsOrder, nTnsOrderCodes ); /*Q0*/
1011 : }
1012 :
1013 0 : Word16 DecodeTnsFilterOrder( Decoder_State *st, const Word16 index, Word16 *pValue )
1014 : {
1015 : (void) index;
1016 :
1017 0 : return DecodeUsingTable( st, pValue, codesTnsOrder, nTnsOrderCodes ); /*Q0*/
1018 : }
1019 :
1020 : /* Number of TNS filters */
1021 :
1022 0 : void const *GetNumOfTnsFilters( void const *p, const Word16 index, Word16 *pValue )
1023 : {
1024 0 : move16();
1025 0 : *pValue = ( (STnsData const *) p )[index].nFilters; /*Q0*/
1026 0 : move16();
1027 0 : return ( (STnsData const *) p )[index].filter;
1028 : }
1029 :
1030 0 : void *SetNumOfTnsFilters( void *p, const Word16 index, Word16 value )
1031 : {
1032 0 : move16();
1033 0 : ( (STnsData *) p )[index].nFilters = value; /*Q0*/
1034 0 : move16();
1035 0 : return ( (STnsData *) p )[index].filter;
1036 : }
1037 :
1038 : /* TNS enabled/disabled flag */
1039 :
1040 1248537 : void const *GetTnsEnabled( void const *p, const Word16 index, Word16 *pValue )
1041 : {
1042 1248537 : move16();
1043 1248537 : *pValue = 0;
1044 1248537 : if ( ( (STnsData const *) p )[index].nFilters != 0 )
1045 : {
1046 85876 : move16();
1047 85876 : *pValue = 1;
1048 : }
1049 1248537 : return NULL;
1050 : }
1051 :
1052 632464 : void *SetTnsEnabled( void *p, const Word16 index, const Word16 value )
1053 : {
1054 : (void) p, (void) index, (void) value;
1055 632464 : return NULL;
1056 : }
1057 :
1058 : /* Number of TNS filters */
1059 :
1060 85876 : void const *GetNumOfTnsFilters_flt( void const *p, const Word16 index, Word16 *pValue )
1061 : {
1062 85876 : *pValue = (Word16) abs( ( (STnsData const *) p )[index].nFilters );
1063 85876 : return ( (STnsData const *) p )[index].filter;
1064 : }
1065 :
1066 79721 : void *SetNumOfTnsFilters_flt( void *p, const Word16 index, const Word16 value )
1067 : {
1068 79721 : ( (STnsData *) p )[index].nFilters = (Word16) abs( value );
1069 79721 : return ( (STnsData *) p )[index].filter;
1070 : }
1071 1229 : Word16 DecodeTnsFilterOrder_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
1072 : {
1073 : (void) index;
1074 1229 : return DecodeUsingTable( st, pValue, codesTnsOrder, nTnsOrderCodes );
1075 : }
1076 : /* TNS on whitened spectra flag */
1077 :
1078 68634 : void const *GetTnsOnWhite( void const *p, const Word16 index, Word16 *pValue )
1079 : {
1080 68634 : *pValue = ( (STnsData const *) p )[index].tnsOnWhitenedSpectra > 0 ? 1 : 0;
1081 68634 : return NULL;
1082 : }
1083 :
1084 63501 : void *SetTnsOnWhite( void *p, const Word16 index, const Word16 value )
1085 : {
1086 63501 : ( (STnsData *) p )[index].tnsOnWhitenedSpectra = value;
1087 63501 : return NULL;
1088 : }
1089 :
1090 155010 : void const *GetTnsEnabledSingleFilter( void const *p, const Word16 index, Word16 *pValue )
1091 : {
1092 155010 : move16();
1093 155010 : *pValue = 0;
1094 155010 : if ( ( (STnsData const *) p )[index].nFilters > 0 )
1095 : {
1096 1314 : move16();
1097 1314 : *pValue = 1;
1098 : }
1099 155010 : return ( (STnsData const *) p )[index].filter;
1100 : }
1101 :
1102 89901 : void *SetTnsEnabledSingleFilter( void *p, const Word16 index, const Word16 value )
1103 : {
1104 89901 : ( (STnsData *) p )[index].nFilters = value; /*Q0*/
1105 89901 : move16();
1106 89901 : return ( (STnsData *) p )[index].filter;
1107 : }
1108 :
1109 : /*-------------------------------------------------------------------*
1110 : * ResetTnsData()
1111 : *
1112 : *-------------------------------------------------------------------*/
1113 :
1114 2125912 : void ResetTnsData( STnsData *pTnsData )
1115 : {
1116 : Word16 iFilter;
1117 :
1118 :
1119 2125912 : pTnsData->nFilters = 0;
1120 2125912 : move16();
1121 2125912 : pTnsData->tnsOnWhitenedSpectra = 0;
1122 2125912 : move16();
1123 6377736 : FOR( iFilter = 0; iFilter < (Word16) ( sizeof( pTnsData->filter ) / sizeof( pTnsData->filter[0] ) ); iFilter++ )
1124 : {
1125 4251824 : STnsFilter *const pTnsFilter = &pTnsData->filter[iFilter];
1126 4251824 : pTnsFilter->spectrumLength = 0;
1127 4251824 : move16();
1128 4251824 : pTnsFilter->predictionGain = ONE_IN_Q7; /*Q7*/
1129 4251824 : move16();
1130 4251824 : pTnsFilter->predictionGain32 = ONE_IN_Q23; /*Q23*/
1131 4251824 : move32();
1132 4251824 : pTnsFilter->predictionGain_e = PRED_GAIN_E;
1133 4251824 : move16();
1134 4251824 : pTnsFilter->avgSqrCoef = 0;
1135 4251824 : move16();
1136 4251824 : pTnsFilter->filterType = TNS_FILTER_OFF; /*Q0*/
1137 4251824 : move16();
1138 4251824 : ClearTnsFilterCoefficients( pTnsFilter );
1139 : }
1140 2125912 : }
1141 : /*-------------------------------------------------------------------*
1142 : * ClearTnsFilterCoefficients()
1143 : *
1144 : *-------------------------------------------------------------------*/
1145 :
1146 7982162 : void ClearTnsFilterCoefficients(
1147 : STnsFilter *pTnsFilter )
1148 : {
1149 7982162 : move16();
1150 7982162 : pTnsFilter->order = 0;
1151 7982162 : move16();
1152 : assert( TNS_MAX_FILTER_ORDER == 8 );
1153 7982162 : move16();
1154 7982162 : move16();
1155 7982162 : move16();
1156 7982162 : move16();
1157 7982162 : move16();
1158 7982162 : move16();
1159 7982162 : move16();
1160 7982162 : move16();
1161 7982162 : pTnsFilter->coefIndex[0] = 0;
1162 7982162 : pTnsFilter->coefIndex[1] = 0;
1163 7982162 : pTnsFilter->coefIndex[2] = 0;
1164 7982162 : pTnsFilter->coefIndex[3] = 0;
1165 7982162 : pTnsFilter->coefIndex[4] = 0;
1166 7982162 : pTnsFilter->coefIndex[5] = 0;
1167 7982162 : pTnsFilter->coefIndex[6] = 0;
1168 7982162 : pTnsFilter->coefIndex[7] = 0;
1169 7982162 : }
1170 :
1171 : /** Inverse quantization for reflection coefficients.
1172 : *
1173 : * @param index input quantized values.
1174 : * @param parCoeff output reflection coefficients.
1175 : * @param order number of coefficients/values.
1176 : */
1177 368143 : static void Index2Parcor( const Word16 index[] /*Q0*/, Word16 parCoeff[] /*Q15*/, Word16 order /*Q0*/ )
1178 : {
1179 : const Word16 *values;
1180 : Word16 i;
1181 :
1182 368143 : move16();
1183 368143 : values = tnsCoeff4; /*Q15*/
1184 :
1185 1690607 : FOR( i = 0; i < order; i++ )
1186 : {
1187 1322464 : move16();
1188 1322464 : parCoeff[i] = values[( index[i] + INDEX_SHIFT )]; /*Q15*/
1189 : }
1190 368143 : return;
1191 : }
1192 :
1193 :
1194 : /* Linear prediction analysis filter. */
1195 49964336 : static Word32 FIRLattice(
1196 : const Word16 order, /*Q0*/
1197 : const Word16 *parCoeff /*Q15*/,
1198 : Word32 *state, /*Q0*/
1199 : Word32 x /* Q0 */
1200 : )
1201 : {
1202 : Word16 i;
1203 : Word32 tmpSave, tmp;
1204 :
1205 :
1206 49964336 : tmpSave = x;
1207 49964336 : move32();
1208 278001594 : FOR( i = 0; i < order - 1; i++ )
1209 : {
1210 228037258 : tmp = L_add( state[i], Mpy_32_16_1( x, parCoeff[i] ) ); /*Q0*/
1211 228037258 : x = L_add( x, Mpy_32_16_1( state[i], parCoeff[i] ) ); /* exponent: 31+0 */
1212 228037258 : state[i] = tmpSave; /*Q0*/
1213 228037258 : move32();
1214 228037258 : tmpSave = tmp; /*Q0*/
1215 228037258 : move32();
1216 : }
1217 :
1218 : /* last stage: only need half operations */
1219 49964336 : x = L_add( x, Mpy_32_16_1( state[order - 1], parCoeff[order - 1] ) ); /*Q0*/
1220 49964336 : state[order - 1] = tmpSave; /*Q0*/
1221 49964336 : move32();
1222 :
1223 49964336 : return x; /*Q0*/
1224 : }
1225 :
1226 57151630 : static Word32 IIRLattice( Word16 order /*Q0*/, const Word16 *parCoeff /*Q15*/, Word32 *state /*Q0*/, Word32 x /*Q0*/ )
1227 : {
1228 : Word16 i;
1229 :
1230 :
1231 : /* first stage: no need to calculate state[order-1] */
1232 57151630 : x = Msub_32_16( x, state[order - 1], parCoeff[order - 1] ); /*Q0*/
1233 :
1234 312856218 : FOR( i = order - 2; i >= 0; i-- )
1235 : {
1236 255704588 : x = Msub_32_16( x, state[i], parCoeff[i] ); /*Q0*/
1237 255704588 : state[i + 1] = Madd_32_16( state[i], x, parCoeff[i] ); /*Q0*/
1238 255704588 : move32();
1239 : }
1240 :
1241 57151630 : move32();
1242 57151630 : state[0] = x; /*Q0*/
1243 57151630 : return x; /*Q0*/
1244 : }
1245 : /** TNS analysis/synthesis filter.
1246 : * @param spectrum input spectrum values.
1247 : * @param numOfLines number of lines in the spectrum.
1248 : * @param parCoeff filter (PARCOR) coefficients.
1249 : * @param order filter order.
1250 : * @param filter function that implements filtering.
1251 : By this function it is defined whether analysis or synthesis is performed.
1252 : * @param output filtered output spectrum values.
1253 : Inplace operation is supported, so it can be equal to spectrum.
1254 : */
1255 368143 : static void TnsFilter(
1256 : const Word32 spectrum[], /*Qx*/
1257 : const Word16 numOfLines, /*Q0*/
1258 : const Word16 parCoeff[], /*Q15*/
1259 : const Word16 order, /*Q0*/
1260 : TLinearPredictionFilter filter,
1261 : Word32 *state, /*Q0*/
1262 : Word32 output[] /*Qx*/ )
1263 : {
1264 : Word16 j;
1265 :
1266 :
1267 368143 : assert( ( order >= 0 ) && ( order <= TNS_MAX_FILTER_ORDER ) );
1268 368143 : assert( ( numOfLines > 0 ) || ( ( numOfLines == 0 ) && ( order == 0 ) ) );
1269 :
1270 368143 : IF( order == 0 )
1271 : {
1272 :
1273 127473 : test();
1274 127473 : IF( s_and( ( spectrum != output ), numOfLines > 0 ) )
1275 : {
1276 0 : Copy32( spectrum, output, numOfLines ); /*Qx*/
1277 : }
1278 : }
1279 : ELSE
1280 : {
1281 : {
1282 :
1283 107356636 : FOR( j = 0; j < numOfLines; j++ )
1284 : {
1285 107115966 : move32();
1286 107115966 : output[j] = filter( order, parCoeff, state, spectrum[j] ); /*Qx*/
1287 : }
1288 : }
1289 : }
1290 368143 : return;
1291 : }
1292 :
1293 465347 : static void ITF_TnsFilter_fx(
1294 : const Word32 spectrum[], /*Qx*/
1295 : const Word16 numOfLines, /*Q0*/
1296 : const Word16 A[], /* ifdef FIX_ITF_OVERFLOW Q_A else Q14 */
1297 : const Word16 Q_A,
1298 : const Word16 order, /*Q0*/
1299 : Word32 output[] /*Qx*/ )
1300 : {
1301 : Word16 i, j;
1302 : Word32 buf[ITF_MAX_FILTER_ORDER + N_MAX];
1303 : Word32 *p;
1304 : Word16 shift;
1305 465347 : assert( ( order >= 0 ) && ( order <= ITF_MAX_FILTER_ORDER ) );
1306 465347 : assert( ( numOfLines > 0 ) || ( ( numOfLines == 0 ) && ( order == 0 ) ) );
1307 :
1308 465347 : IF( order == 0 )
1309 : {
1310 :
1311 403055 : test();
1312 403055 : IF( s_and( ( spectrum != output ), numOfLines > 0 ) )
1313 : {
1314 0 : Copy32( spectrum, output, numOfLines ); /*Qx*/
1315 : }
1316 : }
1317 : ELSE
1318 : {
1319 62292 : shift = sub( 15, Q_A );
1320 :
1321 62292 : p = buf + ITF_MAX_FILTER_ORDER;
1322 62292 : set32_fx( buf, 0, ITF_MAX_FILTER_ORDER );
1323 62292 : Copy32( spectrum, p, numOfLines ); /*Qx*/
1324 20664452 : FOR( j = 0; j < numOfLines; j++ )
1325 : {
1326 : Word32 L_tmp;
1327 :
1328 20602160 : L_tmp = L_add( p[0], 0 );
1329 164817280 : FOR( i = 1; i < order; i++ )
1330 : {
1331 144215120 : L_tmp = L_add_sat( L_tmp, L_shl( Mpy_32_16_1( p[-i], A[i] ), shift ) ); /*Qx*/
1332 : }
1333 20602160 : output[j] = L_tmp; /*Qx*/
1334 20602160 : move32();
1335 20602160 : ++p;
1336 : }
1337 : }
1338 465347 : return;
1339 : }
1340 :
1341 162626 : static void ITF_GetFilterParameters_fx(
1342 : Word32 rxx[], /*Qx*/
1343 : const Word16 maxOrder, /*Q0*/
1344 : Word16 *A, /* ifdef FIX_ITF_OVERFLOW Q_A else Q14 */
1345 : Word16 *Q_A,
1346 : Word16 *predictionGain /*Q7*/ )
1347 : {
1348 : Word16 i, j, i_2, tmp;
1349 : Word16 parCoeff[ITF_MAX_FILTER_ORDER];
1350 : Word32 epsP[ITF_MAX_FILTER_ORDER + 1], L_tmp;
1351 :
1352 : /* compute filter in ParCor form with LeRoux-Gueguen algorithm */
1353 162626 : L_tmp = E_LPC_schur( rxx, parCoeff, epsP, maxOrder );
1354 : BASOP_SATURATE_WARNING_OFF_EVS /* Allow saturation, this value is compared against a threshold. */
1355 162626 : *predictionGain = divide3232( L_shr( epsP[0], PRED_GAIN_E ), L_tmp ); /*Q7*/
1356 162626 : move16();
1357 : BASOP_SATURATE_WARNING_ON_EVS
1358 :
1359 : {
1360 : Word32 A32[ITF_MAX_FILTER_ORDER];
1361 : Word16 tmp1_l, tmp1_h, tmp2_l, tmp2_h;
1362 :
1363 : /* Convert ParCor / reflection coefficients to LPC */
1364 162626 : A32[0] = 134217728l /*1.0 Q27*/;
1365 162626 : move32(); /* Q11+16 */
1366 162626 : A32[1] = L_shr( L_deposit_h( parCoeff[0] ), 4 ); /* Q11+16 */
1367 162626 : move32();
1368 :
1369 1301008 : FOR( i = 1; i < maxOrder; i++ )
1370 : {
1371 1138382 : L_tmp = L_shr( L_deposit_h( parCoeff[i] ), 3 ); /* Q11+16 */
1372 :
1373 1138382 : i_2 = shr( i, 1 );
1374 3089894 : FOR( j = 0; j < i_2; j++ )
1375 : {
1376 1951512 : tmp1_l = L_Extract_lc( A32[i - 1 - j + 1], &tmp1_h );
1377 1951512 : tmp2_l = L_Extract_lc( A32[j + 1], &tmp2_h );
1378 1951512 : A32[j + 1] = Mac_32( A32[j + 1], parCoeff[i], 0, tmp1_h, tmp1_l ); /*+= parCoeff[i] * a[i-1-j+1]; Q11+16*/
1379 1951512 : move32();
1380 1951512 : A32[i - 1 - j + 1] = Mac_32( A32[i - 1 - j + 1], parCoeff[i], 0, tmp2_h, tmp2_l ); /*+= parCoeff[i] * tmp; Q11+16*/
1381 1951512 : move32();
1382 : }
1383 1138382 : IF( s_and( i, 1 ) )
1384 : {
1385 650504 : tmp2_l = L_Extract_lc( A32[j + 1], &tmp2_h );
1386 650504 : A32[j + 1] = Mac_32( A32[j + 1], parCoeff[i], 0, tmp2_h, tmp2_l ); /*+= parCoeff[i] * a[j+1]; Q11+16*/
1387 650504 : move32();
1388 : }
1389 :
1390 1138382 : A32[i + 1] = L_shr( L_deposit_h( parCoeff[i] ), 4 ); /* Q11+16 */
1391 1138382 : move32();
1392 : }
1393 :
1394 162626 : tmp = 3;
1395 162626 : move16(); /* assume Q11 -> Q14 */
1396 1463634 : FOR( i = 0; i < maxOrder; i++ )
1397 : {
1398 1301008 : tmp = s_min( tmp, norm_l( A32[i] ) );
1399 : }
1400 1463634 : FOR( i = 0; i < maxOrder; i++ )
1401 : {
1402 1301008 : A[i] = round_fx( L_shl( A32[i], tmp ) ); /* Q11+tmp */
1403 1301008 : move16();
1404 : }
1405 162626 : *Q_A = add( 11, tmp );
1406 162626 : move16();
1407 : }
1408 162626 : return;
1409 : }
|