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 1708501 : 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 1708501 : ResetTnsData( pTnsData );
83 :
84 1708501 : if ( pTnsConfig->maxOrder <= 0 )
85 : {
86 0 : return 0;
87 : }
88 :
89 1708501 : CalculateTnsFilt( pTnsConfig, pSpectrum, pTnsData, predictionGain );
90 :
91 1708501 : TnsDecision( pTnsConfig, hTranDet, isTCX10, ltp_gain, pTnsData );
92 :
93 1708501 : return ( pTnsData->nFilters > 0 ) ? 1 : 0;
94 : }
95 :
96 :
97 : /*---------------------------------------------------------------------*
98 : * EncodeTnsData()
99 : *
100 : *
101 : *---------------------------------------------------------------------*/
102 :
103 21983462 : 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 21983462 : *pnSize = 0;
112 21983462 : *pnBits = 0;
113 :
114 21983462 : if ( pTnsConfig->nMaxFilters > 1 )
115 : {
116 18457520 : if ( pTnsConfig->allowTnsOnWhite )
117 : {
118 17522991 : if ( pTnsConfig->iFilterBorders[0] < 512 )
119 : {
120 681411 : GetParameters( &tnsEnabledOnWhiteSWBTCX10BitMap, 1, pTnsData, &stream, pnSize, pnBits );
121 : }
122 : else
123 : {
124 16841580 : GetParameters( &tnsEnabledOnWhiteSWBTCX20BitMap, 1, pTnsData, &stream, pnSize, pnBits );
125 : }
126 : }
127 : else
128 : {
129 934529 : if ( pTnsConfig->iFilterBorders[0] < 512 )
130 : {
131 26582 : GetParameters( &tnsEnabledSWBTCX10BitMap, 1, pTnsData, &stream, pnSize, pnBits );
132 : }
133 : else
134 : {
135 907947 : GetParameters( &tnsEnabledSWBTCX20BitMap, 1, pTnsData, &stream, pnSize, pnBits );
136 : }
137 : }
138 : }
139 : else
140 : {
141 3525942 : GetParameters( &tnsEnabledWBTCX20BitMap, 1, pTnsData, &stream, pnSize, pnBits );
142 : }
143 :
144 21983462 : return;
145 : }
146 :
147 :
148 : /*---------------------------------------------------------------------*
149 : * WriteTnsData()
150 : *
151 : *
152 : *---------------------------------------------------------------------*/
153 :
154 11873628 : 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 11873628 : if ( pTnsConfig->nMaxFilters > 1 )
163 : {
164 9739941 : if ( pTnsConfig->allowTnsOnWhite )
165 : {
166 8805412 : if ( pTnsConfig->iFilterBorders[0] < 512 )
167 : {
168 452936 : WriteToBitstream( &tnsEnabledOnWhiteSWBTCX10BitMap, 1, &stream, pnSize, hBstr, pnBits );
169 : }
170 : else
171 : {
172 8352476 : WriteToBitstream( &tnsEnabledOnWhiteSWBTCX20BitMap, 1, &stream, pnSize, hBstr, pnBits );
173 : }
174 : }
175 : else
176 : {
177 934529 : if ( pTnsConfig->iFilterBorders[0] < 512 )
178 : {
179 26582 : WriteToBitstream( &tnsEnabledSWBTCX10BitMap, 1, &stream, pnSize, hBstr, pnBits );
180 : }
181 : else
182 : {
183 907947 : WriteToBitstream( &tnsEnabledSWBTCX20BitMap, 1, &stream, pnSize, hBstr, pnBits );
184 : }
185 : }
186 : }
187 : else
188 : {
189 2133687 : WriteToBitstream( &tnsEnabledWBTCX20BitMap, 1, &stream, pnSize, hBstr, pnBits );
190 : }
191 :
192 11873628 : 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 36523101 : 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 36523101 : float *const pWorkBuffer = &workBuffer[order]; /* temp pointer */
216 :
217 328707909 : for ( i = 0; i < order; i++ )
218 : {
219 292184808 : workBuffer[i] = input[i];
220 292184808 : pWorkBuffer[i] = input[i + 1];
221 : }
222 :
223 328707909 : for ( i = 0; i < order; i++ )
224 : {
225 292184808 : if ( workBuffer[0] < 1.0f / 65536.0f )
226 : {
227 0 : tmp = 0;
228 : }
229 : else
230 : {
231 292184808 : tmp = -pWorkBuffer[i] / workBuffer[0];
232 : }
233 :
234 : /* compensate for calculation inaccuracies limit reflection coefs to ]-1,1[ */
235 292184808 : tmp = min( 0.999f, max( -0.999f, tmp ) );
236 :
237 292184808 : parCoeff[i] = tmp;
238 1607016444 : for ( j = i; j < order; j++ )
239 : {
240 1314831636 : tmp2 = pWorkBuffer[j] + tmp * workBuffer[j - i];
241 1314831636 : workBuffer[j - i] += tmp * pWorkBuffer[j];
242 1314831636 : pWorkBuffer[j] = tmp2;
243 : }
244 : }
245 :
246 36523101 : 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 36523101 : 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 36523101 : const float *values = tnsCoeff4;
265 36523101 : int16_t *indexes = pTnsFilter->coefIndex;
266 :
267 : /* Variable initialization */
268 : /* compute TNS filter in lattice (ParCor) form with LeRoux-Gueguen algorithm */
269 36523101 : pTnsFilter->predictionGain = AutoToParcor( rxx, parCoeff, maxOrder );
270 :
271 : /* non-linear quantization of TNS lattice coefficients with given resolution */
272 36523101 : Parcor2Index( parCoeff, indexes, maxOrder );
273 :
274 : /* reduce filter order by truncating trailing zeros */
275 36523101 : i = maxOrder - 1;
276 205076595 : while ( ( i >= 0 ) && ( indexes[i] == 0 ) )
277 : {
278 168553494 : --i;
279 : /* Loop condition */
280 : }
281 36523101 : pTnsFilter->order = i + 1;
282 :
283 : /* compute avg(coef*coef) */
284 36523101 : pTnsFilter->avgSqrCoef = 0;
285 160154415 : for ( i = pTnsFilter->order - 1; i >= 0; i-- )
286 : {
287 123631314 : const float value = values[indexes[i] + INDEX_SHIFT];
288 :
289 : /* Variable initialization */
290 123631314 : pTnsFilter->avgSqrCoef += value * value;
291 : }
292 36523101 : pTnsFilter->avgSqrCoef /= maxOrder;
293 :
294 36523101 : return;
295 : }
296 :
297 :
298 : /*---------------------------------------------------------------------*
299 : * Parcor2Index()
300 : *
301 : * Quantization for reflection coefficients
302 : *---------------------------------------------------------------------*/
303 :
304 36523101 : 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 36523101 : const int16_t nValues = 1 << TNS_COEF_RES;
311 36523101 : const float *values = tnsCoeff4;
312 : int16_t i;
313 : int16_t iIndex;
314 : float x;
315 :
316 328707909 : for ( i = 0; i < order; i++ )
317 : {
318 292184808 : iIndex = 1;
319 292184808 : x = parCoeff[i];
320 : /* Variable initialization */
321 292184808 : assert( ( x >= -1.0f ) && ( x <= 1.0f ) );
322 2638231857 : while ( ( iIndex < nValues ) && ( x > 0.5f * ( values[iIndex - 1] + values[iIndex] ) ) )
323 : {
324 2346047049 : ++iIndex;
325 : /* Loop condition */
326 : }
327 292184808 : index[i] = ( iIndex - 1 ) - INDEX_SHIFT;
328 : }
329 :
330 36523101 : return;
331 : }
332 :
333 :
334 : /*---------------------------------------------------------------------*
335 : * CalculateTnsFilt()
336 : *
337 : *
338 : *---------------------------------------------------------------------*/
339 :
340 21983462 : 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 65950386 : for ( i = 0; i < TNS_MAX_NUM_OF_FILTERS; i++ )
356 : {
357 43966924 : set_f( norms[i], 0, MAX_SUBDIVISIONS );
358 : }
359 :
360 : /* Calculate norms for each spectrum part */
361 62424444 : for ( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
362 : {
363 40440982 : idx0 = pTnsConfig->iFilterBorders[iFilter + 1];
364 40440982 : idx1 = pTnsConfig->iFilterBorders[iFilter];
365 40440982 : nSubdivisions = pTnsConfig->pTnsParameters[iFilter].nSubdivisions;
366 :
367 : /* Variable initialization */
368 40440982 : assert( pTnsConfig->pTnsParameters[iFilter].nSubdivisions <= MAX_SUBDIVISIONS );
369 159948034 : for ( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
370 : {
371 119507052 : iStartLine = idx0 + ( idx1 - idx0 ) * iSubdivisions / nSubdivisions;
372 119507052 : iEndLine = idx0 + ( idx1 - idx0 ) * ( iSubdivisions + 1 ) / nSubdivisions;
373 :
374 : /* Variable initialization */
375 119507052 : 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 62424444 : for ( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
381 : {
382 40440982 : idx0 = pTnsConfig->iFilterBorders[iFilter + 1];
383 40440982 : idx1 = pTnsConfig->iFilterBorders[iFilter];
384 40440982 : spectrumLength = idx1 - idx0;
385 40440982 : pFilter = pTnsData->filter + iFilter;
386 40440982 : nSubdivisions = pTnsConfig->pTnsParameters[iFilter].nSubdivisions;
387 :
388 40440982 : set_f( rxx, 0, TNS_MAX_FILTER_ORDER + 1 ); /* WMOPS: This initialization is required */
389 :
390 : /* Variable initialization */
391 149998849 : for ( iSubdivisions = 0; ( iSubdivisions < nSubdivisions ) && ( norms[iFilter][iSubdivisions] > HLM_MIN_NRG ); iSubdivisions++ )
392 : {
393 109557867 : fac = 1.0f / norms[iFilter][iSubdivisions];
394 109557867 : iStartLine = idx0 + spectrumLength * iSubdivisions / nSubdivisions;
395 109557867 : iEndLine = idx0 + spectrumLength * ( iSubdivisions + 1 ) / nSubdivisions;
396 109557867 : pWindow = tnsAcfWindow;
397 :
398 : /* For additional loop condition */
399 : /* Variable initialization */
400 986020803 : for ( lag = 1; lag <= pTnsConfig->maxOrder; lag++ )
401 : {
402 876462936 : rxx[lag] += fac * ( *pWindow ) * dotp( pSpectrum + iStartLine, pSpectrum + iStartLine + lag, iEndLine - iStartLine - lag );
403 876462936 : pWindow++;
404 : }
405 : }
406 :
407 40440982 : if ( iSubdivisions == nSubdivisions ) /* meaning there is no subdivision with low energy */
408 : {
409 36523101 : rxx[0] = (float) pTnsConfig->pTnsParameters[iFilter].nSubdivisions;
410 36523101 : pFilter->spectrumLength = spectrumLength;
411 : /* Limit the maximum order to spectrum length/4 */
412 36523101 : GetFilterParameters( rxx, min( pTnsConfig->maxOrder, pFilter->spectrumLength / 4 ), pFilter );
413 : }
414 : }
415 :
416 21983462 : if ( predictionGain )
417 : {
418 6548 : assert( pTnsConfig->nMaxFilters == 1 );
419 6548 : *predictionGain = pTnsData->filter->predictionGain;
420 : }
421 :
422 21983462 : return;
423 : }
424 :
425 :
426 : /*---------------------------------------------------------------------*
427 : * TnsDecision()
428 : *
429 : *
430 : *---------------------------------------------------------------------*/
431 :
432 1708501 : 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 4351531 : for ( iFilter = pTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
447 : {
448 2643030 : pFilter = pTnsData->filter + iFilter;
449 2643030 : pTnsParameters = pTnsConfig->pTnsParameters + iFilter;
450 :
451 : /* TNS decision function */
452 2643030 : if ( ( pFilter->predictionGain > pTnsParameters->minPredictionGain ) || ( pFilter->avgSqrCoef > pTnsParameters->minAvgSqrCoef ) )
453 : {
454 124305 : if ( pTnsData->nFilters > 0 || isTCX10 || ltp_gain < 0.6f || hTranDet == NULL )
455 : {
456 124305 : ++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 2518725 : 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 35640 : ClearTnsFilterCoefficients( pFilter );
475 35640 : pFilter->order = 1;
476 35640 : ++pTnsData->nFilters;
477 : }
478 : else
479 : {
480 2483085 : ClearTnsFilterCoefficients( pFilter );
481 : }
482 : }
483 :
484 1708501 : return;
485 : }
|