Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <assert.h>
38 : #include <stdint.h>
39 : #include "options.h"
40 : #include "wmc_auto.h"
41 : #include "cnst.h"
42 : #include "rom_com.h"
43 : #include "prot.h"
44 : #include "stat_com.h"
45 :
46 : /*----------------------------------------------------------------------------
47 : * Local constants
48 : *---------------------------------------------------------------------------*/
49 :
50 : #define HLM_MIN_NRG ( PCM16_TO_FLT_FAC * 2 * NORM_MDCT_FACTOR / ( 640 * 640 ) )
51 :
52 : #define MAX_SUBDIVISIONS 3
53 :
54 :
55 : /*----------------------------------------------------------------------------
56 : * Local prototypes
57 : *---------------------------------------------------------------------------*/
58 :
59 : static void GetFilterParameters( const float rxx[], const int16_t maxOrder, STnsFilter *pTnsFilter );
60 :
61 : static void Parcor2Index( const float parCoeff[], int16_t index[], const int16_t order );
62 :
63 : static void TnsDecision( STnsConfig const *pTnsConfig, TRAN_DET_HANDLE hTranDet, const int16_t isTCX10, const float ltp_gain, STnsData *pTnsData );
64 :
65 :
66 : /*---------------------------------------------------------------------*
67 : * DetectTnsFilt()
68 : *
69 : *
70 : *---------------------------------------------------------------------*/
71 :
72 161953 : int16_t DetectTnsFilt(
73 : const STnsConfig *pTnsConfig, /* i : TNS Configuration struct */
74 : const float pSpectrum[], /* i : MDCT spectrum */
75 : TRAN_DET_HANDLE hTranDet, /* i : transient detection handle */
76 : const int16_t isTCX10, /* i : TCX10 or TCX20? */
77 : const float ltp_gain, /* i : LTP gain */
78 : STnsData *pTnsData, /* o : TNS data struct */
79 : float *predictionGain /* o : TNS prediction gain */
80 : )
81 : {
82 161953 : ResetTnsData( pTnsData );
83 :
84 161953 : if ( pTnsConfig->maxOrder <= 0 )
85 : {
86 0 : return 0;
87 : }
88 :
89 161953 : CalculateTnsFilt( pTnsConfig, pSpectrum, pTnsData, predictionGain );
90 :
91 161953 : TnsDecision( pTnsConfig, hTranDet, isTCX10, ltp_gain, pTnsData );
92 :
93 161953 : return ( pTnsData->nFilters > 0 ) ? 1 : 0;
94 : }
95 :
96 :
97 : /*---------------------------------------------------------------------*
98 : * EncodeTnsData()
99 : *
100 : *
101 : *---------------------------------------------------------------------*/
102 :
103 1454820 : void EncodeTnsData(
104 : STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */
105 : STnsData const *pTnsData, /* i : TNS data struct (quantized param) */
106 : int16_t *stream, /* o : internal data stream */
107 : int16_t *pnSize, /* o : number of written parameters */
108 : int16_t *pnBits /* o : number of written bits */
109 : )
110 : {
111 1454820 : *pnSize = 0;
112 1454820 : *pnBits = 0;
113 :
114 1454820 : if ( pTnsConfig->nMaxFilters > 1 )
115 : {
116 1287771 : if ( pTnsConfig->allowTnsOnWhite )
117 : {
118 1171879 : if ( pTnsConfig->iFilterBorders[0] < 512 )
119 : {
120 43066 : GetParameters( &tnsEnabledOnWhiteSWBTCX10BitMap, 1, pTnsData, &stream, pnSize, pnBits );
121 : }
122 : else
123 : {
124 1128813 : GetParameters( &tnsEnabledOnWhiteSWBTCX20BitMap, 1, pTnsData, &stream, pnSize, pnBits );
125 : }
126 : }
127 : else
128 : {
129 115892 : if ( pTnsConfig->iFilterBorders[0] < 512 )
130 : {
131 4154 : GetParameters( &tnsEnabledSWBTCX10BitMap, 1, pTnsData, &stream, pnSize, pnBits );
132 : }
133 : else
134 : {
135 111738 : GetParameters( &tnsEnabledSWBTCX20BitMap, 1, pTnsData, &stream, pnSize, pnBits );
136 : }
137 : }
138 : }
139 : else
140 : {
141 167049 : GetParameters( &tnsEnabledWBTCX20BitMap, 1, pTnsData, &stream, pnSize, pnBits );
142 : }
143 :
144 1454820 : return;
145 : }
146 :
147 :
148 : /*---------------------------------------------------------------------*
149 : * WriteTnsData()
150 : *
151 : *
152 : *---------------------------------------------------------------------*/
153 :
154 812687 : void WriteTnsData(
155 : const STnsConfig *pTnsConfig, /* i : TNS Configuration struct */
156 : const int16_t *stream, /* i : internal data stream */
157 : int16_t *pnSize, /* o : number of written parameters */
158 : BSTR_ENC_HANDLE hBstr, /* o : bitstream */
159 : int16_t *pnBits /* o : number of written bits */
160 : )
161 : {
162 812687 : if ( pTnsConfig->nMaxFilters > 1 )
163 : {
164 706375 : if ( pTnsConfig->allowTnsOnWhite )
165 : {
166 590483 : if ( pTnsConfig->iFilterBorders[0] < 512 )
167 : {
168 29131 : WriteToBitstream( &tnsEnabledOnWhiteSWBTCX10BitMap, 1, &stream, pnSize, hBstr, pnBits );
169 : }
170 : else
171 : {
172 561352 : WriteToBitstream( &tnsEnabledOnWhiteSWBTCX20BitMap, 1, &stream, pnSize, hBstr, pnBits );
173 : }
174 : }
175 : else
176 : {
177 115892 : if ( pTnsConfig->iFilterBorders[0] < 512 )
178 : {
179 4154 : WriteToBitstream( &tnsEnabledSWBTCX10BitMap, 1, &stream, pnSize, hBstr, pnBits );
180 : }
181 : else
182 : {
183 111738 : WriteToBitstream( &tnsEnabledSWBTCX20BitMap, 1, &stream, pnSize, hBstr, pnBits );
184 : }
185 : }
186 : }
187 : else
188 : {
189 106312 : WriteToBitstream( &tnsEnabledWBTCX20BitMap, 1, &stream, pnSize, hBstr, pnBits );
190 : }
191 :
192 812687 : return;
193 : }
194 :
195 :
196 : /*********************************************************************************************/
197 : /* Definitions of functions used in the mapping between TNS parameters and a bitstream. */
198 : /*********************************************************************************************/
199 :
200 : /*---------------------------------------------------------------------*
201 : * AutoToParcor()
202 : *
203 : * Autocorrelation to parcor coefficients
204 : *---------------------------------------------------------------------*/
205 :
206 2583512 : static float AutoToParcor(
207 : const float input[], /* i : autocorrelation */
208 : float parCoeff[], /* o : parcor coeffs */
209 : const int16_t order /* i : prediction order */
210 : )
211 : {
212 : int16_t i, j;
213 : float tmp, tmp2;
214 : float workBuffer[2 * TNS_MAX_FILTER_ORDER];
215 2583512 : float *const pWorkBuffer = &workBuffer[order]; /* temp pointer */
216 :
217 23251608 : for ( i = 0; i < order; i++ )
218 : {
219 20668096 : workBuffer[i] = input[i];
220 20668096 : pWorkBuffer[i] = input[i + 1];
221 : }
222 :
223 23251608 : for ( i = 0; i < order; i++ )
224 : {
225 20668096 : if ( workBuffer[0] < 1.0f / 65536.0f )
226 : {
227 0 : tmp = 0;
228 : }
229 : else
230 : {
231 20668096 : tmp = -pWorkBuffer[i] / workBuffer[0];
232 : }
233 :
234 : /* compensate for calculation inaccuracies limit reflection coefs to ]-1,1[ */
235 20668096 : tmp = min( 0.999f, max( -0.999f, tmp ) );
236 :
237 20668096 : parCoeff[i] = tmp;
238 113674528 : for ( j = i; j < order; j++ )
239 : {
240 93006432 : tmp2 = pWorkBuffer[j] + tmp * workBuffer[j - i];
241 93006432 : workBuffer[j - i] += tmp * pWorkBuffer[j];
242 93006432 : pWorkBuffer[j] = tmp2;
243 : }
244 : }
245 :
246 2583512 : return ( ( input[0] + 1e-30f ) / ( workBuffer[0] + 1e-30f ) );
247 : }
248 :
249 :
250 : /*---------------------------------------------------------------------*
251 : * GetFilterParameters()
252 : *
253 : * Get TNS filter parameters from autocorrelation
254 : *---------------------------------------------------------------------*/
255 :
256 2583512 : static void GetFilterParameters(
257 : const float rxx[], /* i : auto correlation */
258 : const int16_t maxOrder, /* i : max. prediction order */
259 : STnsFilter *pTnsFilter /* i : TNS filter coeffs */
260 : )
261 : {
262 : int16_t i;
263 : float parCoeff[TNS_MAX_FILTER_ORDER];
264 2583512 : const float *values = tnsCoeff4;
265 2583512 : int16_t *indexes = pTnsFilter->coefIndex;
266 :
267 : /* Variable initialization */
268 : /* compute TNS filter in lattice (ParCor) form with LeRoux-Gueguen algorithm */
269 2583512 : pTnsFilter->predictionGain = AutoToParcor( rxx, parCoeff, maxOrder );
270 :
271 : /* non-linear quantization of TNS lattice coefficients with given resolution */
272 2583512 : Parcor2Index( parCoeff, indexes, maxOrder );
273 :
274 : /* reduce filter order by truncating trailing zeros */
275 2583512 : i = maxOrder - 1;
276 14348815 : while ( ( i >= 0 ) && ( indexes[i] == 0 ) )
277 : {
278 11765303 : --i;
279 : /* Loop condition */
280 : }
281 2583512 : pTnsFilter->order = i + 1;
282 :
283 : /* compute avg(coef*coef) */
284 2583512 : pTnsFilter->avgSqrCoef = 0;
285 11486305 : for ( i = pTnsFilter->order - 1; i >= 0; i-- )
286 : {
287 8902793 : const float value = values[indexes[i] + INDEX_SHIFT];
288 :
289 : /* Variable initialization */
290 8902793 : pTnsFilter->avgSqrCoef += value * value;
291 : }
292 2583512 : pTnsFilter->avgSqrCoef /= maxOrder;
293 :
294 2583512 : return;
295 : }
296 :
297 :
298 : /*---------------------------------------------------------------------*
299 : * Parcor2Index()
300 : *
301 : * Quantization for reflection coefficients
302 : *---------------------------------------------------------------------*/
303 :
304 2583512 : static void Parcor2Index(
305 : const float parCoeff[], /* i : parcor coefficients */
306 : int16_t index[], /* o : quantized parcor coeffs */
307 : const int16_t order /* i : order */
308 : )
309 : {
310 2583512 : const int16_t nValues = 1 << TNS_COEF_RES;
311 2583512 : const float *values = tnsCoeff4;
312 : int16_t i;
313 : int16_t iIndex;
314 : float x;
315 :
316 23251608 : for ( i = 0; i < order; i++ )
317 : {
318 20668096 : iIndex = 1;
319 20668096 : x = parCoeff[i];
320 : /* Variable initialization */
321 20668096 : assert( ( x >= -1.0f ) && ( x <= 1.0f ) );
322 186656934 : while ( ( iIndex < nValues ) && ( x > 0.5f * ( values[iIndex - 1] + values[iIndex] ) ) )
323 : {
324 165988838 : ++iIndex;
325 : /* Loop condition */
326 : }
327 20668096 : index[i] = ( iIndex - 1 ) - INDEX_SHIFT;
328 : }
329 :
330 2583512 : return;
331 : }
332 :
333 :
334 : /*---------------------------------------------------------------------*
335 : * CalculateTnsFilt()
336 : *
337 : *
338 : *---------------------------------------------------------------------*/
339 :
340 1454820 : void CalculateTnsFilt(
341 : STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */
342 : const float pSpectrum[], /* i : MDCT spectrum */
343 : STnsData *pTnsData, /* o : TNS data struct */
344 : float *predictionGain /* o : TNS prediction gain */
345 : )
346 : {
347 : float norms[TNS_MAX_NUM_OF_FILTERS][MAX_SUBDIVISIONS];
348 : int16_t i, iFilter, idx0, idx1, nSubdivisions, iSubdivisions, spectrumLength;
349 : int16_t iStartLine, iEndLine, lag;
350 : float fac;
351 : float rxx[TNS_MAX_FILTER_ORDER + 1];
352 : const float *pWindow;
353 : STnsFilter *pFilter;
354 :
355 4364460 : for ( i = 0; i < TNS_MAX_NUM_OF_FILTERS; i++ )
356 : {
357 2909640 : set_f( norms[i], 0, MAX_SUBDIVISIONS );
358 : }
359 :
360 : /* Calculate norms for each spectrum part */
361 4197411 : for ( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
362 : {
363 2742591 : idx0 = pTnsConfig->iFilterBorders[iFilter + 1];
364 2742591 : idx1 = pTnsConfig->iFilterBorders[iFilter];
365 2742591 : nSubdivisions = pTnsConfig->pTnsParameters[iFilter].nSubdivisions;
366 :
367 : /* Variable initialization */
368 2742591 : assert( pTnsConfig->pTnsParameters[iFilter].nSubdivisions <= MAX_SUBDIVISIONS );
369 10746888 : for ( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
370 : {
371 8004297 : iStartLine = idx0 + ( idx1 - idx0 ) * iSubdivisions / nSubdivisions;
372 8004297 : iEndLine = idx0 + ( idx1 - idx0 ) * ( iSubdivisions + 1 ) / nSubdivisions;
373 :
374 : /* Variable initialization */
375 8004297 : norms[iFilter][iSubdivisions] = sum2_f( pSpectrum + iStartLine, iEndLine - iStartLine );
376 : }
377 : }
378 :
379 : /* Calculate normalized autocorrelation for spectrum subdivision and get TNS filter parameters based on it */
380 4197411 : for ( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
381 : {
382 2742591 : idx0 = pTnsConfig->iFilterBorders[iFilter + 1];
383 2742591 : idx1 = pTnsConfig->iFilterBorders[iFilter];
384 2742591 : spectrumLength = idx1 - idx0;
385 2742591 : pFilter = pTnsData->filter + iFilter;
386 2742591 : nSubdivisions = pTnsConfig->pTnsParameters[iFilter].nSubdivisions;
387 :
388 2742591 : set_f( rxx, 0, TNS_MAX_FILTER_ORDER + 1 ); /* WMOPS: This initialization is required */
389 :
390 : /* Variable initialization */
391 10374737 : for ( iSubdivisions = 0; ( iSubdivisions < nSubdivisions ) && ( norms[iFilter][iSubdivisions] > HLM_MIN_NRG ); iSubdivisions++ )
392 : {
393 7632146 : fac = 1.0f / norms[iFilter][iSubdivisions];
394 7632146 : iStartLine = idx0 + spectrumLength * iSubdivisions / nSubdivisions;
395 7632146 : iEndLine = idx0 + spectrumLength * ( iSubdivisions + 1 ) / nSubdivisions;
396 7632146 : pWindow = tnsAcfWindow;
397 :
398 : /* For additional loop condition */
399 : /* Variable initialization */
400 68689314 : for ( lag = 1; lag <= pTnsConfig->maxOrder; lag++ )
401 : {
402 61057168 : rxx[lag] += fac * ( *pWindow ) * dotp( pSpectrum + iStartLine, pSpectrum + iStartLine + lag, iEndLine - iStartLine - lag );
403 61057168 : pWindow++;
404 : }
405 : }
406 :
407 2742591 : if ( iSubdivisions == nSubdivisions ) /* meaning there is no subdivision with low energy */
408 : {
409 2583512 : rxx[0] = (float) pTnsConfig->pTnsParameters[iFilter].nSubdivisions;
410 2583512 : pFilter->spectrumLength = spectrumLength;
411 : /* Limit the maximum order to spectrum length/4 */
412 2583512 : GetFilterParameters( rxx, min( pTnsConfig->maxOrder, pFilter->spectrumLength / 4 ), pFilter );
413 : }
414 : }
415 :
416 1454820 : if ( predictionGain )
417 : {
418 371 : assert( pTnsConfig->nMaxFilters == 1 );
419 371 : *predictionGain = pTnsData->filter->predictionGain;
420 : }
421 :
422 1454820 : return;
423 : }
424 :
425 :
426 : /*---------------------------------------------------------------------*
427 : * TnsDecision()
428 : *
429 : *
430 : *---------------------------------------------------------------------*/
431 :
432 161953 : static void TnsDecision(
433 : STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */
434 : TRAN_DET_HANDLE hTranDet, /* i : transient detection handle */
435 : const int16_t isTCX10, /* i : TCX10 or TCX20? */
436 : const float ltp_gain, /* i : LTP gain */
437 : STnsData *pTnsData /* i/o: TNDS data structure */
438 : )
439 : {
440 : int16_t iFilter;
441 : float maxEnergyChange;
442 : STnsFilter *pFilter;
443 : const struct TnsParameters *pTnsParameters;
444 :
445 : /* We check the filter's decisions in the opposite direction */
446 439798 : for ( iFilter = pTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
447 : {
448 277845 : pFilter = pTnsData->filter + iFilter;
449 277845 : pTnsParameters = pTnsConfig->pTnsParameters + iFilter;
450 :
451 : /* TNS decision function */
452 277845 : if ( ( pFilter->predictionGain > pTnsParameters->minPredictionGain ) || ( pFilter->avgSqrCoef > pTnsParameters->minAvgSqrCoef ) )
453 : {
454 20377 : if ( pTnsData->nFilters > 0 || isTCX10 || ltp_gain < 0.6f || hTranDet == NULL )
455 : {
456 20377 : ++pTnsData->nFilters;
457 : }
458 : else
459 : {
460 0 : maxEnergyChange = GetTCXMaxenergyChange( hTranDet, isTCX10, NSUBBLOCKS, 3 );
461 0 : if ( maxEnergyChange >= pTnsParameters->minEnergyChange )
462 : {
463 0 : ++pTnsData->nFilters;
464 : }
465 : else
466 : {
467 0 : ClearTnsFilterCoefficients( pFilter );
468 : }
469 : }
470 : }
471 257468 : else if ( pTnsData->nFilters > 0 ) /* If a previous filter is turned on */
472 : {
473 : /* Since TNS filter of order 0 is not allowed we haved to signal in the stream filter of order 1 with the 0th coefficient equal to 0 */
474 5018 : ClearTnsFilterCoefficients( pFilter );
475 5018 : pFilter->order = 1;
476 5018 : ++pTnsData->nFilters;
477 : }
478 : else
479 : {
480 252450 : ClearTnsFilterCoefficients( pFilter );
481 : }
482 : }
483 :
484 161953 : return;
485 : }
|