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 <math.h>
41 : #include "cnst.h"
42 : #include "prot.h"
43 : #include "wmc_auto.h"
44 : #include "ivas_prot.h"
45 : #include "ivas_rom_com.h"
46 : #ifdef DEBUGGING
47 : #include <string.h>
48 : #endif
49 : #ifdef DEBUG_PLOT
50 : #include "deb_out.h"
51 : #endif
52 :
53 : /*-------------------------------------------------------------------*
54 : * HBAutocorrelation()
55 : *
56 : *
57 : *-------------------------------------------------------------------*/
58 :
59 108975 : void HBAutocorrelation(
60 : TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */
61 : const int16_t left_overlap_mode, /* i : overlap mode of left window half */
62 : const int16_t right_overlap_mode, /* i : overlap mode of right window half */
63 : float speech[], /* i : synthesis */
64 : int16_t L_frame, /* i : frame length */
65 : float *r /* o : autocorrelations vector */
66 : )
67 : {
68 : int16_t i, j, left_overlap, right_overlap;
69 : float s;
70 : float xn_buf[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX];
71 :
72 : /*-----------------------------------------------------------*
73 : * Windowing *
74 : *-----------------------------------------------------------*/
75 :
76 108975 : WindowSignal( hTcxCfg, hTcxCfg->tcx_offset, left_overlap_mode, right_overlap_mode, &left_overlap, &right_overlap, speech, &L_frame, xn_buf, 1, 0 );
77 :
78 : /*-----------------------------------------------------------*
79 : * Autocorrelation *
80 : *-----------------------------------------------------------*/
81 :
82 1961550 : for ( i = 0; i <= M; i++ )
83 : {
84 1852575 : s = 0.0;
85 :
86 1628698175 : for ( j = 0; j < L_frame + ( left_overlap + right_overlap ) / 2 - i; j++ )
87 : {
88 1626845600 : s += xn_buf[j] * xn_buf[j + i];
89 : }
90 1852575 : r[i] = s;
91 : }
92 :
93 108975 : if ( r[0] < 100.0 )
94 : {
95 324 : r[0] = 100.0;
96 : }
97 :
98 108975 : return;
99 : }
100 :
101 :
102 : /*-------------------------------------------------------------------*
103 : * TNSAnalysisStereo()
104 : *
105 : *
106 : *-------------------------------------------------------------------*/
107 :
108 : #define SIMILAR_TNS_THRESHOLD ( 0.04f )
109 : #define TNS_GAIN_THRESHOLD_FOR_WHITE ( 3.0f )
110 :
111 705898 : void TNSAnalysisStereo(
112 : Encoder_State **sts, /* i : encoder state handle */
113 : float *mdst_spectrum[CPE_CHANNELS][NB_DIV], /* o : MDST spectrum */
114 : const int16_t bWhitenedDomain, /* i : whitened domain flag */
115 : int16_t tnsSize[CPE_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm */
116 : int16_t tnsBits[CPE_CHANNELS][NB_DIV], /* i : number of tns bits in the frame */
117 : int16_t param_core[][NB_DIV * NPRM_DIV], /* o : TNS parameters */
118 : const int16_t mct_on /* i : flag mct block (1) or stereo (0) */
119 : )
120 : {
121 : int16_t ch, k, L_spec, L_frame, nSubframes, iFilter;
122 : float *spectrum;
123 705898 : Encoder_State *st = NULL;
124 705898 : TCX_ENC_HANDLE hTcxEnc = NULL;
125 : int16_t individual_decision[NB_DIV];
126 705898 : float maxPredictionGain = 0.f, meanPredictionGain;
127 :
128 705898 : individual_decision[0] = 0;
129 705898 : individual_decision[1] = 0;
130 705898 : L_spec = -1;
131 705898 : L_frame = -1;
132 :
133 : /* TNS filter analysis, loop over channels */
134 2117694 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
135 : {
136 1411796 : st = sts[ch];
137 1411796 : if ( st->mct_chan_mode == MCT_CHAN_MODE_IGNORE )
138 : {
139 126223 : continue;
140 : }
141 :
142 1285573 : hTcxEnc = st->hTcxEnc;
143 :
144 1285573 : nSubframes = ( hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
145 :
146 2600768 : for ( k = 0; k < nSubframes; k++ )
147 : {
148 : /* reset tns on whitened domain flag */
149 1315195 : if ( !bWhitenedDomain )
150 : {
151 661880 : hTcxEnc->bTnsOnWhithenedSpectra[k] = 0;
152 661880 : hTcxEnc->fUseTns[k] = 0;
153 : }
154 :
155 1315195 : if ( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
156 : {
157 :
158 1292867 : spectrum = hTcxEnc->spectrum[k];
159 1292867 : L_frame = hTcxEnc->L_frameTCX;
160 1292867 : st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )];
161 1292867 : L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
162 :
163 : /*-----------------------------------------------------------*
164 : * Temporal Noise Shaping analysis *
165 : *-----------------------------------------------------------*/
166 :
167 1292867 : if ( hTcxEnc->transform_type[k] == TCX_5 )
168 : {
169 : /* rearrange LF sub-window lines prior to TNS analysis & filtering */
170 15305 : tcx5TnsGrouping( L_frame >> 2, L_spec >> 1, spectrum );
171 : }
172 :
173 : /* WMOPS: All initializations are either for safety or static (tables) and thus not to be counted */
174 1292867 : ResetTnsData( &hTcxEnc->tnsData[k] );
175 1292867 : if ( st->hTcxCfg->pCurrentTnsConfig->maxOrder <= 0 )
176 : {
177 0 : break;
178 : }
179 :
180 1292867 : CalculateTnsFilt( st->hTcxCfg->pCurrentTnsConfig, spectrum, &hTcxEnc->tnsData[k], NULL );
181 : }
182 : }
183 : }
184 :
185 705898 : if ( !mct_on )
186 : {
187 : /* TNS decision */
188 : /* if framing differs between channels, keep the filter decision per channel */
189 165282 : if ( ( sts[0]->hTcxEnc->transform_type[0] != sts[1]->hTcxEnc->transform_type[0] &&
190 1260 : sts[0]->hTcxEnc->transform_type[1] != sts[1]->hTcxEnc->transform_type[1] ) ||
191 164026 : sts[0]->hTcxCfg->fIsTNSAllowed != sts[1]->hTcxCfg->fIsTNSAllowed )
192 : {
193 1256 : individual_decision[0] = individual_decision[1] = 1;
194 : }
195 164026 : else if ( bWhitenedDomain )
196 : {
197 82013 : nSubframes = ( sts[0]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
198 165789 : for ( k = 0; k < nSubframes; k++ )
199 : {
200 83776 : if ( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] != sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] )
201 : {
202 441 : individual_decision[k] = 1;
203 : }
204 : }
205 : }
206 :
207 : /* framing equal, check for similar filters, if very similar (also indicator for and M signal),
208 : * use at least the same decision, maybe use the same filter
209 : */
210 : {
211 : int16_t isTCX10;
212 165282 : isTCX10 = ( sts[0]->hTcxEnc->tcxMode == TCX_20 ) ? 0 : 1;
213 :
214 165282 : nSubframes = ( sts[0]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
215 :
216 334692 : for ( k = 0; k < nSubframes; k++ )
217 : {
218 169410 : if ( sts[0]->hTcxCfg->fIsTNSAllowed && individual_decision[k] != 1 && ( !bWhitenedDomain || sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
219 : {
220 164739 : float maxPredGain = -1.0f;
221 164739 : sts[0]->hTcxCfg->pCurrentTnsConfig = &sts[0]->hTcxCfg->tnsConfig[sts[0]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[0]->last_core == ACELP_CORE )];
222 164739 : sts[1]->hTcxCfg->pCurrentTnsConfig = &sts[1]->hTcxCfg->tnsConfig[sts[1]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[1]->last_core == ACELP_CORE )];
223 :
224 : #ifdef DEBUGGING
225 : assert( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters == sts[1]->hTcxCfg->pCurrentTnsConfig->nMaxFilters );
226 : #endif
227 472698 : for ( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
228 : {
229 : STnsFilter *pFilter[2];
230 : struct TnsParameters const *pTnsParameters[2];
231 307959 : pFilter[0] = sts[0]->hTcxEnc->tnsData[k].filter + iFilter;
232 307959 : pTnsParameters[0] = sts[0]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter;
233 307959 : pFilter[1] = sts[1]->hTcxEnc->tnsData[k].filter + iFilter;
234 307959 : pTnsParameters[1] = sts[1]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter;
235 :
236 : #ifdef DEBUGGING
237 : assert( pTnsParameters[0]->startLineFrequency == pTnsParameters[1]->startLineFrequency );
238 : assert( pTnsParameters[0]->nSubdivisions == pTnsParameters[1]->nSubdivisions );
239 : #endif
240 : /* if prediction gain and avgSqrCoef are both close we are pretty sure the filters are quite similar, use the avg of
241 : * both filters for the decision
242 : */
243 307959 : meanPredictionGain = ( pFilter[0]->predictionGain + pFilter[1]->predictionGain ) * 0.5f;
244 307959 : maxPredictionGain = max( maxPredictionGain, meanPredictionGain );
245 :
246 307959 : if ( ( pFilter[0]->predictionGain > pTnsParameters[0]->minPredictionGain ) && ( sts[0]->element_brate < IVAS_80k ) &&
247 9024 : ( pFilter[1]->predictionGain > pTnsParameters[1]->minPredictionGain ) && ( sts[0]->hTcxEnc->tnsData[k].nFilters == sts[1]->hTcxEnc->tnsData[k].nFilters ) )
248 : {
249 4825 : pFilter[0]->predictionGain = pFilter[1]->predictionGain = meanPredictionGain; /* more TNS filter sync at 48kbps */
250 : }
251 307959 : if ( ( fabs( pFilter[0]->predictionGain - pFilter[1]->predictionGain ) < SIMILAR_TNS_THRESHOLD * meanPredictionGain ) &&
252 203119 : ( sts[0]->hTcxEnc->tnsData[k].nFilters == sts[1]->hTcxEnc->tnsData[k].nFilters ) )
253 203119 : {
254 203119 : float maxAvgSqrCoef = max( pFilter[0]->avgSqrCoef, pFilter[1]->avgSqrCoef );
255 203119 : float meanLtpGain = ( sts[0]->hTcxEnc->tcxltp_gain + sts[1]->hTcxEnc->tcxltp_gain ) * 0.5f;
256 203119 : maxPredGain = max( maxPredGain, meanPredictionGain );
257 203119 : if ( ( meanPredictionGain > pTnsParameters[0]->minPredictionGain ) || ( maxAvgSqrCoef > pTnsParameters[0]->minAvgSqrCoef ) )
258 : {
259 7125 : if ( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 || sts[1]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || meanLtpGain < 0.6f )
260 : {
261 6451 : ++sts[0]->hTcxEnc->tnsData[k].nFilters;
262 6451 : pFilter[0]->filterType = TNS_FILTER_ON;
263 6451 : ++sts[1]->hTcxEnc->tnsData[k].nFilters;
264 6451 : pFilter[1]->filterType = TNS_FILTER_ON;
265 : }
266 : else
267 : {
268 674 : const float maxEnergyChange = ( GetTCXMaxenergyChange( sts[0]->hTranDet, isTCX10, NSUBBLOCKS, 3 ) + GetTCXMaxenergyChange( sts[1]->hTranDet, isTCX10, NSUBBLOCKS, 3 ) ) * 0.5f;
269 :
270 674 : if ( maxEnergyChange >= pTnsParameters[0]->minEnergyChange )
271 : {
272 664 : ++sts[0]->hTcxEnc->tnsData[k].nFilters;
273 664 : pFilter[0]->filterType = TNS_FILTER_ON;
274 664 : ++sts[1]->hTcxEnc->tnsData[k].nFilters;
275 664 : pFilter[1]->filterType = TNS_FILTER_ON;
276 : }
277 : else
278 : {
279 10 : pFilter[0]->filterType = TNS_FILTER_OFF;
280 10 : pFilter[1]->filterType = TNS_FILTER_OFF;
281 : }
282 : }
283 : }
284 195994 : else if ( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 && sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */
285 : {
286 203 : pFilter[0]->filterType = TNS_FILTER_ON_ZERO;
287 203 : pFilter[1]->filterType = TNS_FILTER_ON_ZERO;
288 203 : ++sts[0]->hTcxEnc->tnsData[k].nFilters;
289 203 : ++sts[1]->hTcxEnc->tnsData[k].nFilters;
290 : }
291 195791 : else if ( sts[0]->hTcxEnc->tnsData[k].nFilters != sts[1]->hTcxEnc->tnsData[k].nFilters ) /* sanity check */
292 : {
293 0 : assert( 0 );
294 : }
295 : else
296 : {
297 195791 : pFilter[0]->filterType = TNS_FILTER_OFF;
298 195791 : pFilter[1]->filterType = TNS_FILTER_OFF;
299 : }
300 203119 : if ( ( pFilter[0]->filterType == TNS_FILTER_ON ) && ( pFilter[1]->filterType == TNS_FILTER_ON ) && ( sts[0]->element_brate < IVAS_80k ) )
301 : {
302 6000 : int16_t tmpIntValue = 0;
303 : int16_t tmpCoeff[TNS_MAX_FILTER_ORDER];
304 6000 : int16_t i, maxOrder = max( pFilter[0]->order, pFilter[1]->order );
305 :
306 6000 : set_s( tmpCoeff, 0, TNS_MAX_FILTER_ORDER );
307 45463 : for ( i = 0; i < maxOrder; i++ )
308 : {
309 39463 : tmpIntValue = (int16_t) max( tmpIntValue, abs( pFilter[0]->coefIndex[i] - pFilter[1]->coefIndex[i] ) );
310 : }
311 6000 : if ( tmpIntValue == 1 ) /* the TNS coefficients are sufficiently similar to equalize the two filters */
312 : {
313 27535 : for ( i = maxOrder - 1; i >= 0; i-- )
314 : {
315 23931 : tmpCoeff[i] = ( abs( pFilter[0]->coefIndex[i] ) < abs( pFilter[1]->coefIndex[i] ) ? pFilter[0]->coefIndex[i] : pFilter[1]->coefIndex[i] );
316 23931 : if ( ( tmpIntValue > 0 ) && ( tmpCoeff[i] == 0 ) )
317 : {
318 5723 : maxOrder--;
319 : }
320 : else
321 : {
322 18208 : tmpIntValue = 0;
323 : }
324 : }
325 : /* make sure that maxOrder is non zero and not all coefficients are zero (could happen in rare cases) */
326 3604 : if ( maxOrder > 0 )
327 : {
328 32436 : for ( i = TNS_MAX_FILTER_ORDER - 1; i >= 0; i-- )
329 : {
330 28832 : pFilter[0]->coefIndex[i] = pFilter[1]->coefIndex[i] = tmpCoeff[i];
331 : }
332 :
333 3604 : pFilter[0]->order = pFilter[1]->order = maxOrder;
334 : }
335 : }
336 : }
337 : }
338 : else
339 : {
340 104840 : individual_decision[k] = 1;
341 : }
342 : }
343 :
344 164739 : if ( individual_decision[k] == 0 )
345 : {
346 80736 : sts[0]->hTcxEnc->fUseTns[k] = ( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 ) ? 1 : 0;
347 80736 : sts[1]->hTcxEnc->fUseTns[k] = ( sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) ? 1 : 0;
348 : }
349 : else
350 : {
351 84003 : sts[0]->hTcxEnc->tnsData[k].nFilters = 0;
352 84003 : sts[1]->hTcxEnc->tnsData[k].nFilters = 0;
353 84003 : sts[0]->hTcxEnc->fUseTns[k] = 0;
354 84003 : sts[1]->hTcxEnc->fUseTns[k] = 0;
355 244554 : for ( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
356 : {
357 160551 : sts[0]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF;
358 160551 : sts[1]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF;
359 : }
360 : }
361 :
362 164739 : if ( !bWhitenedDomain && individual_decision[k] == 0 && maxPredGain < TNS_GAIN_THRESHOLD_FOR_WHITE && sts[0]->hTcxEnc->transform_type[k] != TCX_5 )
363 : {
364 39649 : sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1;
365 39649 : sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1;
366 39649 : sts[0]->hTcxEnc->tnsData[k].nFilters = 0;
367 39649 : sts[1]->hTcxEnc->tnsData[k].nFilters = 0;
368 39649 : sts[0]->hTcxEnc->fUseTns[k] = 0;
369 39649 : sts[1]->hTcxEnc->fUseTns[k] = 0;
370 112057 : for ( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
371 : {
372 72408 : ClearTnsFilterCoefficients( sts[0]->hTcxEnc->tnsData[k].filter + iFilter );
373 72408 : ClearTnsFilterCoefficients( sts[1]->hTcxEnc->tnsData[k].filter + iFilter );
374 : }
375 : }
376 164739 : maxPredictionGain = max( maxPredictionGain, maxPredGain );
377 : }
378 : }
379 : }
380 : }
381 :
382 : /* individual decision for each channel */
383 2117694 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
384 : {
385 1411796 : if ( sts[ch]->mct_chan_mode == MCT_CHAN_MODE_IGNORE )
386 : {
387 126223 : continue;
388 : }
389 :
390 : int16_t isTCX10;
391 1285573 : isTCX10 = ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 0 : 1;
392 :
393 1285573 : nSubframes = ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
394 :
395 2600768 : for ( k = 0; k < nSubframes; k++ )
396 : {
397 1315195 : if ( sts[ch]->hTcxCfg->fIsTNSAllowed && ( individual_decision[k] || mct_on ) &&
398 567793 : ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
399 : {
400 1131395 : float maxPredGain = -1.0f;
401 :
402 1131395 : sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )];
403 :
404 3301325 : for ( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
405 : {
406 : STnsFilter *pFilter;
407 : const struct TnsParameters *pTnsParameters;
408 2169930 : pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter;
409 2169930 : pTnsParameters = sts[ch]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter;
410 2169930 : maxPredGain = max( maxPredGain, pFilter->predictionGain );
411 :
412 2169930 : if ( ( pFilter->predictionGain > pTnsParameters->minPredictionGain ) || ( pFilter->avgSqrCoef > pTnsParameters->minAvgSqrCoef ) )
413 : {
414 134280 : if ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || sts[ch]->hTcxEnc->tcxltp_gain < 0.6f )
415 : {
416 114899 : ++sts[ch]->hTcxEnc->tnsData[k].nFilters;
417 114899 : pFilter->filterType = TNS_FILTER_ON;
418 : }
419 : else
420 : {
421 19381 : const float maxEnergyChange = GetTCXMaxenergyChange( sts[ch]->hTranDet, isTCX10, NSUBBLOCKS, 3 );
422 :
423 19381 : if ( maxEnergyChange >= pTnsParameters->minEnergyChange )
424 : {
425 18203 : ++sts[ch]->hTcxEnc->tnsData[k].nFilters;
426 18203 : pFilter->filterType = TNS_FILTER_ON;
427 : }
428 : else
429 : {
430 1178 : pFilter->filterType = TNS_FILTER_OFF;
431 : }
432 : }
433 : }
434 2035650 : else if ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */
435 : {
436 12832 : pFilter->filterType = TNS_FILTER_ON_ZERO;
437 12832 : ++sts[ch]->hTcxEnc->tnsData[k].nFilters;
438 : }
439 : else
440 : {
441 2022818 : pFilter->filterType = TNS_FILTER_OFF;
442 : }
443 : }
444 :
445 1131395 : sts[ch]->hTcxEnc->fUseTns[k] = ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) ? 1 : 0;
446 :
447 1131395 : if ( !bWhitenedDomain && maxPredGain < TNS_GAIN_THRESHOLD_FOR_WHITE && sts[ch]->hTcxEnc->transform_type[k] != TCX_5 )
448 : {
449 560254 : sts[ch]->hTcxEnc->fUseTns[k] = 0;
450 560254 : sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1;
451 560254 : sts[ch]->hTcxEnc->tnsData[k].nFilters = 0;
452 1633868 : for ( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
453 : {
454 1073614 : ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter );
455 1073614 : sts[ch]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF;
456 : }
457 : }
458 1131395 : maxPredictionGain = max( maxPredictionGain, maxPredGain );
459 : }
460 : }
461 : }
462 :
463 :
464 : /* we have the decision, set filter data accordingly */
465 2117694 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
466 : {
467 1411796 : if ( sts[ch]->mct_chan_mode == MCT_CHAN_MODE_IGNORE )
468 : {
469 126223 : continue;
470 : }
471 :
472 1285573 : nSubframes = ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
473 :
474 2600768 : for ( k = 0; k < nSubframes; k++ )
475 : {
476 1315195 : if ( sts[ch]->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
477 : {
478 1292867 : sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )];
479 :
480 3757613 : for ( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
481 : {
482 : STnsFilter *pFilter;
483 2464746 : pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter;
484 2464746 : switch ( pFilter->filterType )
485 : {
486 2370728 : case TNS_FILTER_OFF:
487 2370728 : ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter );
488 2370728 : break;
489 9782 : case TNS_FILTER_ON_ZERO:
490 : /* Since TNS filter of order 0 is not allowed we have to signal in the stream filter of order 1 with the 0th coefficient equal to 0 */
491 9782 : ClearTnsFilterCoefficients( pFilter );
492 9782 : pFilter->order = 1;
493 9782 : break;
494 : }
495 2464746 : }
496 : }
497 : }
498 : }
499 :
500 : /* Apply filters, loop over channels */
501 2117694 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
502 : {
503 1411796 : st = sts[ch];
504 1411796 : if ( st->mct_chan_mode == MCT_CHAN_MODE_IGNORE )
505 : {
506 126223 : continue;
507 : }
508 :
509 1285573 : nSubframes = ( st->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
510 :
511 2600768 : for ( k = 0; k < nSubframes; k++ )
512 : {
513 1315195 : if ( bWhitenedDomain && ( ch > 0 ) && /* test for identical TNS filter data in both channels */
514 296440 : sts[0]->hTcxCfg->fIsTNSAllowed && sts[0]->hTcxEnc->fUseTns[k] &&
515 32636 : sts[1]->hTcxCfg->fIsTNSAllowed && sts[1]->hTcxEnc->fUseTns[k] )
516 : {
517 56500 : int16_t equalFilterData = ( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters == sts[1]->hTcxCfg->pCurrentTnsConfig->nMaxFilters &&
518 18824 : sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] == sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] &&
519 16542 : sts[0]->hTcxEnc->tnsData[k].nFilters == sts[1]->hTcxEnc->tnsData[k].nFilters )
520 : ? 1
521 37662 : : 0;
522 18838 : if ( equalFilterData )
523 : {
524 31141 : for ( iFilter = st->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
525 : {
526 26831 : const int16_t *pDataCh0 = (const int16_t *) &sts[0]->hTcxEnc->tnsData[k].filter[iFilter];
527 26831 : const int16_t *pDataCh1 = (const int16_t *) &sts[1]->hTcxEnc->tnsData[k].filter[iFilter];
528 26831 : int16_t i = 2 + TNS_MAX_FILTER_ORDER; /* excl. informative float data. Portable? */
529 :
530 226721 : while ( ( i >= 0 ) && ( pDataCh0[i] == pDataCh1[i] ) )
531 : {
532 199890 : i--;
533 : }
534 26831 : if ( i >= 0 )
535 : {
536 10842 : equalFilterData = 0;
537 10842 : break;
538 : }
539 : }
540 15152 : if ( equalFilterData )
541 : {
542 4310 : st->hTcxEnc->tnsData[k].nFilters *= -1; /* signals common TNS */
543 : }
544 : }
545 : }
546 1315195 : if ( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || st->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
547 : {
548 1292867 : L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
549 1292867 : spectrum = st->hTcxEnc->spectrum[k];
550 : /* If TNS should be used then get the residual after applying it inplace in the spectrum */
551 1292867 : if ( st->hTcxEnc->fUseTns[k] )
552 : {
553 72785 : st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[st->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )];
554 :
555 72785 : ApplyTnsFilter( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], spectrum, 1 );
556 : }
557 :
558 1292867 : if ( st->hTcxEnc->transform_type[k] == TCX_5 )
559 : {
560 15305 : tcx5TnsUngrouping( L_frame >> 2, L_spec >> 1, st->hTcxEnc->spectrum[k], ENC );
561 : }
562 :
563 1292867 : st->hTcxEnc->tnsData[k].tnsOnWhitenedSpectra = st->hTcxEnc->bTnsOnWhithenedSpectra[k];
564 :
565 1292867 : EncodeTnsData( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], param_core[ch] + k * NPRM_DIV + 1 + NOISE_FILL_RANGES + LTPSIZE, tnsSize[ch] + k, tnsBits[ch] + k );
566 : }
567 :
568 1315195 : if ( st->hTcxEnc->transform_type[k] == TCX_5 )
569 : {
570 30610 : tcx5SpectrumInterleaving( st->hTcxCfg->tcx5SizeFB, st->hTcxEnc->spectrum[k] );
571 30610 : tcx5SpectrumInterleaving( st->hTcxCfg->tcx5SizeFB, mdst_spectrum[ch][k] );
572 : }
573 : }
574 : }
575 :
576 705898 : return;
577 : }
578 :
579 :
580 : /*-------------------------------------------------------------------*
581 : * TNSAnalysis()
582 : *
583 : *
584 : *-------------------------------------------------------------------*/
585 :
586 237660 : void TNSAnalysis(
587 : TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */
588 : const int16_t L_frame, /* i : frame length */
589 : int16_t L_spec, /* i : length of the spectrum */
590 : const int16_t transform_type, /* i : transform type for the frame/subframe - TCX20 | TCX10 | TCX 5 (meaning 2 x TCX 5) */
591 : const int16_t isAfterACELP, /* i : Flag indicating if the last frame was ACELP. For the second TCX subframe it should be 0 */
592 : float spectrum[], /* i : MDCT spectrum of the subframe */
593 : TRAN_DET_HANDLE hTranDet, /* i : handle transient detection */
594 : const float ltp_gain, /* i : ltp gain */
595 : STnsData *pTnsData, /* o : TNS data */
596 : int16_t *pfUseTns, /* o : Flag indicating if TNS is used */
597 : float *predictionGain /* o : TNS prediction gain */
598 : )
599 : {
600 : float buff[8]; /* Buffer for the rearrangement of LF TCX5 */
601 :
602 : /* Init TNS */
603 237660 : *pfUseTns = 0;
604 :
605 237660 : if ( hTcxCfg->fIsTNSAllowed )
606 : {
607 161953 : hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[transform_type == TCX_20][isAfterACELP];
608 161953 : L_spec = hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
609 :
610 : /*-----------------------------------------------------------*
611 : * Temporal Noise Shaping analysis *
612 : *-----------------------------------------------------------*/
613 :
614 161953 : if ( transform_type == TCX_5 )
615 : {
616 : /* rearrange LF sub-window lines prior to TNS analysis & filtering */
617 2231 : if ( L_spec < L_frame / 2 )
618 : {
619 2163 : mvr2r( spectrum + 8, spectrum + 16, L_spec / 2 - 8 );
620 2163 : mvr2r( spectrum + L_frame / 4, spectrum + 8, 8 );
621 2163 : mvr2r( spectrum + L_frame / 4 + 8, spectrum + L_spec / 2 + 8, L_spec / 2 - 8 );
622 : }
623 : else
624 : {
625 68 : mvr2r( spectrum + L_frame / 4, buff, 8 );
626 68 : mvr2r( spectrum + 8, spectrum + 16, L_frame / 4 - 8 );
627 68 : mvr2r( buff, spectrum + 8, 8 );
628 : }
629 : }
630 :
631 161953 : *pfUseTns = DetectTnsFilt( hTcxCfg->pCurrentTnsConfig, spectrum, hTranDet, transform_type != TCX_20, ltp_gain, pTnsData, predictionGain );
632 :
633 :
634 : /* If TNS should be used then get the residual after applying it inplace in the spectrum */
635 161953 : if ( *pfUseTns )
636 : {
637 17665 : ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, pTnsData, spectrum, 1 );
638 : }
639 :
640 161953 : if ( transform_type == TCX_5 )
641 : {
642 : /* undo rearrangement of LF sub-window lines prior to TNS analysis */
643 2231 : if ( L_spec < L_frame / 2 )
644 : {
645 2163 : mvr2r( spectrum + L_spec / 2 + 8, spectrum + L_frame / 4 + 8, L_spec / 2 - 8 );
646 2163 : mvr2r( spectrum + 8, spectrum + L_frame / 4, 8 );
647 2163 : mvr2r( spectrum + 16, spectrum + 8, L_spec / 2 - 8 );
648 2163 : set_zero( spectrum + L_spec / 2, L_frame / 4 - L_spec / 2 );
649 2163 : set_zero( spectrum + L_frame / 4 + L_spec / 2, L_frame / 4 - L_spec / 2 );
650 : }
651 : else
652 : {
653 68 : mvr2r( spectrum + 8, buff, 8 );
654 68 : mvr2r( spectrum + 16, spectrum + 8, L_frame / 4 - 8 );
655 68 : mvr2r( buff, spectrum + L_frame / 4, 8 );
656 : }
657 : }
658 : }
659 :
660 237660 : return;
661 : }
662 :
663 :
664 : /*-------------------------------------------------------------------*
665 : * ShapeSpectrum()
666 : *
667 : *
668 : *-------------------------------------------------------------------*/
669 :
670 1471780 : void ShapeSpectrum(
671 : TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */
672 : const float A[], /* i : quantized coefficients NxAz_q[M+1] */
673 : float gainlpc[], /* o : MDCT gains for the previous frame */
674 : const int16_t L_frame_glob, /* i : frame length */
675 : int16_t L_spec, /* i : length of the spectrum */
676 : float spectrum[], /* i/o: MDCT spectrum */
677 : const int16_t fUseTns, /* i : Flag indicating if TNS is used */
678 : Encoder_State *st, /* i/o: encoder state structure */
679 : float *scf /* i : scale factors */
680 : )
681 : {
682 1471780 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
683 : int16_t i, sf_width, L_frame, tcx_offset;
684 : float Ap[M + 2];
685 : float tmp, gamma1;
686 1471780 : float max_low_pre = 0.f, max_high_pre = 0.f;
687 : float sns_int_scf[FDNS_NPTS];
688 1471780 : int32_t total_brate = ( st->element_mode == IVAS_CPE_MDCT ? st->element_brate : st->total_brate );
689 : /*-----------------------------------------------------------*
690 : * Init *
691 : *-----------------------------------------------------------*/
692 :
693 : /* Init lengths */
694 1471780 : L_frame = L_frame_glob;
695 1471780 : tcx_offset = hTcxCfg->tcx_offset;
696 :
697 1471780 : gamma1 = st->gamma;
698 1471780 : if ( st->enableTcxLpc )
699 : {
700 17457 : gamma1 = 1.0f;
701 : }
702 :
703 1471780 : if ( st->element_mode != IVAS_CPE_MDCT ) /* in MDCT, this is already done outside the function */
704 : {
705 237935 : if ( st->last_core == ACELP_CORE )
706 : {
707 7988 : L_frame += tcx_offset;
708 7988 : L_spec += hTcxCfg->tcx_coded_lines >> 2;
709 7988 : if ( hTcxCfg->lfacNext < 0 )
710 : {
711 7988 : L_frame -= hTcxCfg->lfacNext;
712 : }
713 : }
714 : }
715 :
716 1471780 : tcxGetNoiseFillingTilt( A, L_frame, ( total_brate >= ACELP_13k20 && !st->rf_mode ), &st->hTcxEnc->noiseTiltFactor );
717 :
718 : /* Calculate Spectrum Flatness Measure for the TCX Concealment */
719 1471780 : if ( st->enablePlcWaveadjust )
720 : {
721 0 : hTcxCfg->SFM2 = SFM_Cal( spectrum, min( 200, L_frame ) );
722 : }
723 :
724 1471780 : if ( ( total_brate <= ACELP_13k20 && st->bwidth == SWB ) )
725 : {
726 31258 : max_low_pre = 0.f;
727 8173914 : for ( i = 0; i < L_frame; i++ )
728 : {
729 8142656 : tmp = fabsf( spectrum[i] );
730 8142656 : if ( tmp > max_low_pre )
731 : {
732 138748 : max_low_pre = tmp;
733 : }
734 : }
735 :
736 31258 : max_high_pre = 0.f;
737 12245242 : for ( i = 0; i < L_spec - L_frame; i++ )
738 : {
739 12213984 : tmp = fabsf( spectrum[L_frame + i] );
740 12213984 : if ( tmp > max_high_pre )
741 : {
742 2462 : max_high_pre = tmp;
743 : }
744 : }
745 : }
746 :
747 1471780 : if ( st->element_mode == IVAS_CPE_MDCT )
748 : {
749 1233845 : sns_interpolate_scalefactors( &sns_int_scf[0], scf, ENC );
750 1233845 : sns_shape_spectrum( spectrum, st->hTcxCfg->psychParamsCurrent, &sns_int_scf[0], L_frame );
751 1233845 : v_multc( spectrum + L_frame, sns_int_scf[hTcxCfg->psychParamsCurrent->nBands - 1], spectrum + L_frame, L_spec - L_frame );
752 : }
753 : else
754 : {
755 : /*-----------------------------------------------------------*
756 : * Pre-shaping in frequency domain using weighted LPC (Wz) *
757 : *-----------------------------------------------------------*/
758 :
759 237935 : weight_a( A, Ap, gamma1, M );
760 :
761 237935 : lpc2mdct( Ap, M, gainlpc, FDNS_NPTS, 0 );
762 :
763 237935 : mdct_preShaping( spectrum, L_frame, gainlpc );
764 :
765 237935 : v_multc( spectrum + L_frame, 1.f / gainlpc[FDNS_NPTS - 1], spectrum + L_frame, L_spec - L_frame );
766 : }
767 :
768 : /* reduce the peaks in the IGF region, to make life of the core-coder easier... */
769 1471780 : if ( total_brate <= ACELP_13k20 && st->bwidth == SWB )
770 : {
771 : int16_t dist_low, dist_high;
772 : float max_fac;
773 : float max_low, max_low1, max_low2, max_high;
774 :
775 31258 : if ( hTcxEnc->tcx_lpc_shaped_ari )
776 : {
777 13364 : max_fac = 1.5f;
778 : }
779 : else
780 : {
781 17894 : max_fac = 3.f;
782 : }
783 :
784 31258 : sf_width = L_frame / 2;
785 :
786 31258 : max_low2 = 0.f;
787 31258 : dist_low = 0;
788 4102586 : for ( i = 0; i < sf_width; i++ )
789 : {
790 4071328 : tmp = fabsf( spectrum[L_frame - 1 - i] );
791 4071328 : if ( tmp > max_low2 )
792 : {
793 188749 : max_low2 = tmp;
794 188749 : dist_low = i;
795 : }
796 : }
797 :
798 31258 : max_low1 = 0.f;
799 4102586 : for ( i = 0; i < L_frame - sf_width; i++ )
800 : {
801 4071328 : tmp = fabsf( spectrum[L_frame - sf_width - 1 - i] );
802 4071328 : if ( tmp > max_low1 )
803 : {
804 287064 : max_low1 = tmp;
805 : }
806 4071328 : if ( tmp > max_low2 )
807 : {
808 558548 : dist_low = sf_width + i;
809 : }
810 : }
811 :
812 31258 : max_low = max( max_low1, max_low2 );
813 :
814 31258 : max_high = 0.f;
815 31258 : dist_high = 0;
816 12245242 : for ( i = 0; i < L_spec - L_frame; i++ )
817 : {
818 12213984 : tmp = fabsf( spectrum[L_frame + i] );
819 12213984 : if ( tmp > max_high )
820 : {
821 2462 : max_high = tmp;
822 2462 : dist_high = i;
823 : }
824 : }
825 :
826 31258 : if ( ( 4.f * dist_high * max_high > dist_low * max_low ) && ( 16.f * max_low_pre > max_high_pre ) && ( max_high > max_fac * max_low2 ) )
827 : {
828 597 : tmp = max_fac * max_low2 / max_high;
829 597 : v_multc( spectrum + L_frame, tmp, spectrum + L_frame, L_spec - L_frame );
830 : }
831 : }
832 :
833 1471780 : if ( st->element_mode != IVAS_CPE_MDCT && st->tcxonly && st->hTcxEnc->tcxltp && ( st->hTcxEnc->tcxltp_gain > 0.0f ) && !fUseTns )
834 : {
835 3732 : PsychAdaptLowFreqEmph( spectrum, gainlpc );
836 : }
837 :
838 1471780 : return;
839 : }
840 :
841 :
842 : /*-------------------------------------------------------------------*
843 : * GetTransWidth()
844 : *
845 : *
846 : *-------------------------------------------------------------------*/
847 :
848 1073088 : static int16_t GetTransWidth(
849 : const int16_t tcxonly,
850 : const int16_t tcx10,
851 : const float tcxltp_gain,
852 : const int16_t hm_active )
853 : {
854 1073088 : int16_t noiseTransWidth = MIN_NOISE_FILLING_HOLE;
855 :
856 1073088 : if ( tcxonly )
857 : {
858 815633 : noiseTransWidth = HOLE_SIZE_FROM_LTP( max( tcxltp_gain, 0.3125f * hm_active ) );
859 :
860 815633 : if ( tcx10 )
861 : {
862 35389 : noiseTransWidth = 3; /* minimum transition for noise filling in TCX-10 */
863 : }
864 : }
865 :
866 1073088 : return noiseTransWidth;
867 : }
868 :
869 :
870 : /*-----------------------------------------------------------*
871 : * EstimateTCXNoiseLevel()
872 : *
873 : * Estimate and quantize noise factor *
874 : *-----------------------------------------------------------*/
875 :
876 237935 : static void EstimateTCXNoiseLevel(
877 : Encoder_State *st, /* i : encoder state handle */
878 : const float x_orig[], /* i : shaped MDCT spectrum */
879 : float spectrum[], /* i/o: quantized MDCT spectrum */
880 : const float gain_tcx, /* i : global gain */
881 : const int16_t L_frame, /* i : frame length */
882 : const int16_t noiseFillingBorder, /* i : noise filling border */
883 : const int16_t hm_active, /* i : flag indicating if the harmonic model is active */
884 : float *fac_ns, /* o : noise filling level */
885 : int16_t *fac_ns_q /* o : quantized noise filling level */
886 : )
887 : {
888 : int16_t maxNfCalcBw, iStart, noiseTransWidth;
889 237935 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
890 :
891 237935 : maxNfCalcBw = min( noiseFillingBorder, (int16_t) ( hTcxEnc->measuredBwRatio * (float) L_frame + 0.5f ) );
892 :
893 237935 : if ( st->total_brate >= HQ_96k )
894 : {
895 18143 : *fac_ns = 0.0f;
896 18143 : *fac_ns_q = 0;
897 : }
898 : else
899 : {
900 219792 : const int16_t minLevel = ( hTcxEnc->tcx_lpc_shaped_ari && st->element_mode > IVAS_SCE ? 0 : 1 );
901 219792 : iStart = L_frame / ( ( st->total_brate >= ACELP_13k20 && !st->rf_mode ) ? 6 : 8 ); /* noise filling start bin*/
902 219792 : noiseTransWidth = GetTransWidth( st->tcxonly, ( L_frame == st->L_frame >> 1 ), st->hTcxEnc->tcxltp_gain, ( st->hTcxCfg->ctx_hm && st->last_core != ACELP_CORE && hm_active ) );
903 219792 : tcx_noise_factor( x_orig, spectrum, iStart, maxNfCalcBw, noiseTransWidth, L_frame, gain_tcx, hTcxEnc->noiseTiltFactor, fac_ns, fac_ns_q, st->element_mode );
904 :
905 : /* hysteresis for very tonal passages (more stationary noise filling level) */
906 219792 : if ( *fac_ns_q == minLevel )
907 : {
908 15204 : hTcxEnc->noiseLevelMemory_cnt = (int16_t) min( INT16_MAX, 1 + abs( hTcxEnc->noiseLevelMemory_cnt ) ); /* update counter */
909 : }
910 : else
911 : {
912 204588 : if ( ( *fac_ns_q == minLevel + 1 ) && ( abs( hTcxEnc->noiseLevelMemory_cnt ) > 5 ) )
913 : {
914 775 : *fac_ns_q = minLevel; /* reduce noise filling level by one step */
915 775 : *fac_ns = minLevel * 0.75f / ( 1 << NBITS_NOISE_FILL_LEVEL );
916 :
917 : /* signal that noise level is changed by inverting sign of level memory */
918 775 : hTcxEnc->noiseLevelMemory_cnt = ( hTcxEnc->noiseLevelMemory_cnt < 0 ) ? 5 : -1 - hTcxEnc->noiseLevelMemory_cnt;
919 : }
920 : else
921 : {
922 203813 : hTcxEnc->noiseLevelMemory_cnt = 0; /* reset memory since level is too different */
923 : }
924 : }
925 : } /* bitrate */
926 :
927 237935 : return;
928 : }
929 :
930 :
931 : /*-----------------------------------------------------------*
932 : * EstimateStereoTCXNoiseLevel()
933 : *
934 : * Estimate and quantize stereo noise factors
935 : *-----------------------------------------------------------*/
936 :
937 352949 : void EstimateStereoTCXNoiseLevel(
938 : Encoder_State **sts, /* i : state handle */
939 : float *q_spectrum[CPE_CHANNELS][NB_DIV], /* i : quantized MDCT spectrum */
940 : float gain_tcx[][NB_DIV], /* i : global gain */
941 : int16_t L_frame[][NB_DIV], /* i : frame length */
942 : int16_t noiseFillingBorder[][NB_DIV], /* i : noise filling border */
943 : int16_t hm_active[][NB_DIV], /* i : flag indicating if the harmonic model is active */
944 : const int16_t ignore_chan[], /* i : flag indicating whether the channel should be ignored */
945 : float fac_ns[][NB_DIV], /* o : noise filling level */
946 : int16_t param_core[][NB_DIV * NPRM_DIV], /* o : quantized noise filling level */
947 : const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */
948 : )
949 : {
950 : int16_t ch, n;
951 : int16_t nSubframes, maxNfCalcBw, iStart, noiseTransWidth;
952 : float smooth_gain;
953 : float combined_q_spectrum[N_MAX];
954 : int16_t *fac_ns_q;
955 : int32_t total_brate;
956 :
957 1058847 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
958 : {
959 705898 : Encoder_State *st = sts[ch];
960 705898 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
961 :
962 705898 : nSubframes = ( st->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
963 :
964 705898 : if ( ignore_chan[ch] )
965 : {
966 67249 : continue;
967 : }
968 638649 : total_brate = ( st->element_mode == IVAS_CPE_MDCT && !MCT_flag ) ? st->element_brate : st->total_brate;
969 :
970 1292109 : for ( n = 0; n < nSubframes; n++ )
971 : {
972 653460 : fac_ns_q = param_core[ch] + n * NPRM_DIV + 1;
973 653460 : maxNfCalcBw = min( noiseFillingBorder[ch][n], (int16_t) ( hTcxEnc->measuredBwRatio * (float) L_frame[ch][n] + 0.5f ) );
974 653460 : if ( ( total_brate >= HQ_96k && ( st->element_mode <= IVAS_SCE || st->bwidth < SWB ) ) || total_brate > IVAS_192k )
975 : {
976 19488 : fac_ns[ch][n] = 0.0f;
977 19488 : *fac_ns_q = 0;
978 : }
979 : else
980 : {
981 633972 : iStart = L_frame[ch][n] / ( ( total_brate >= ACELP_13k20 && !st->rf_mode ) ? 6 : 8 ); /* noise filling start bin*/
982 :
983 633972 : if ( n == 0 )
984 : {
985 619612 : mvr2r( hTcxEnc->ltpGainMemory, &hTcxEnc->ltpGainMemory[1], N_LTP_GAIN_MEMS - 1 );
986 619612 : hTcxEnc->ltpGainMemory[0] = st->hTcxEnc->tcxltp_gain;
987 : }
988 :
989 633972 : smooth_gain = dotp( hTcxEnc->ltpGainMemory, nf_tw_smoothing_coeffs, N_LTP_GAIN_MEMS );
990 :
991 633972 : noiseTransWidth = GetTransWidth( st->tcxonly, ( L_frame[ch][n] == st->L_frame >> 1 ), smooth_gain, ( st->hTcxCfg->ctx_hm && st->last_core != ACELP_CORE && hm_active[ch][n] ) );
992 :
993 633972 : mvr2r( q_spectrum[ch][n], combined_q_spectrum, L_frame[ch][n] );
994 633972 : tcx_noise_factor( hTcxEnc->spectrum[n], combined_q_spectrum, iStart, maxNfCalcBw, noiseTransWidth, L_frame[ch][n], gain_tcx[ch][n], hTcxEnc->noiseTiltFactor, &fac_ns[ch][n], fac_ns_q, st->element_mode );
995 :
996 : /* hysteresis for very tonal passages (more stationary noise filling level) */
997 633972 : if ( *fac_ns_q == 1 )
998 : {
999 82124 : hTcxEnc->noiseLevelMemory_cnt = (int16_t) min( INT16_MAX, 1 + abs( hTcxEnc->noiseLevelMemory_cnt ) ); /* update counter */
1000 : }
1001 : else
1002 : {
1003 551848 : if ( ( *fac_ns_q == 2 ) && ( abs( hTcxEnc->noiseLevelMemory_cnt ) > 5 ) )
1004 : {
1005 6658 : *fac_ns_q = 1; /* reduce noise filling level by one step */
1006 6658 : fac_ns[ch][n] = 0.75f / ( 1 << NBITS_NOISE_FILL_LEVEL );
1007 :
1008 : /* signal that noise level is changed by inverting sign of level memory */
1009 6658 : hTcxEnc->noiseLevelMemory_cnt = ( hTcxEnc->noiseLevelMemory_cnt < 0 ) ? 5 : -1 - hTcxEnc->noiseLevelMemory_cnt;
1010 : }
1011 : else
1012 : {
1013 545190 : hTcxEnc->noiseLevelMemory_cnt = 0; /* reset memory since level is too different */
1014 : }
1015 : }
1016 : } /* bitrate */
1017 : }
1018 : #ifdef DEBUG_MODE_MDCT
1019 : dbgwrite( &smooth_gain, sizeof( float ), 1, 1, "./res/smooth_gain" );
1020 : dbgwrite( &st->hTcxEnc->tcxltp_gain, sizeof( float ), 1, 1, "./res/tcxltp_gain" );
1021 : dbgwrite( &noiseTransWidth, sizeof( int16_t ), 1, 1, "./res/noiseTrans" );
1022 : dbgwrite( &fac_ns[ch][0], sizeof( float ), 2, 1, "./res/fac_ns" );
1023 : #endif
1024 : }
1025 :
1026 352949 : return;
1027 : }
1028 :
1029 :
1030 : /*-----------------------------------------------------------*
1031 : * DecideTonalSideInfo()
1032 : *
1033 : *
1034 : *-----------------------------------------------------------*/
1035 :
1036 0 : static int16_t DecideTonalSideInfo(
1037 : const float spectrum[],
1038 : const int16_t L_frame_glob,
1039 : float SFM2 )
1040 : {
1041 : float SFM, K, K2;
1042 : int16_t Tonal_SideInfo;
1043 :
1044 0 : SFM = SFM_Cal( spectrum, min( 200, L_frame_glob ) );
1045 :
1046 0 : if ( L_frame_glob <= 256 )
1047 : {
1048 0 : K = 0.4f;
1049 0 : K2 = 0.1f;
1050 : }
1051 0 : else if ( L_frame_glob == 320 || L_frame_glob == 512 )
1052 : {
1053 0 : K = 0.4f;
1054 0 : K2 = 0.1f;
1055 : }
1056 : else /*FrameSize_Core == 640*/
1057 : {
1058 0 : K = 0.35f;
1059 0 : K2 = 0.04f;
1060 : }
1061 :
1062 :
1063 0 : Tonal_SideInfo = 0;
1064 0 : if ( SFM < K )
1065 : {
1066 0 : Tonal_SideInfo = 1;
1067 : }
1068 :
1069 0 : if ( SFM2 < K2 )
1070 : {
1071 0 : Tonal_SideInfo = 1;
1072 : }
1073 :
1074 0 : return Tonal_SideInfo;
1075 : }
1076 :
1077 : /*-----------------------------------------------------------*
1078 : * QuantizeTCXSpectrum()
1079 : *
1080 : *
1081 : *-----------------------------------------------------------*/
1082 :
1083 891395 : void QuantizeTCXSpectrum(
1084 : Encoder_State *st, /* i : state handle */
1085 : const int16_t frame_cnt, /* i : frame counter in the super_frame */
1086 : const float *x_orig, /* i : shaped MDCT spectrum */
1087 : const float *gainlpc, /* i : FDNS gains */
1088 : const Word16 *Aqind, /* i : frame-independent quantized coefficients (M+1) */
1089 : const int16_t tnsSize, /* i : number of tns parameters put into prm */
1090 : const int16_t nb_bits, /* i : bit budget */
1091 : const int16_t vad_hover_flag, /* i : VAD hangover flag */
1092 : int16_t *pL_frameTCX, /* o : full frame length */
1093 : int16_t *pL_frame, /* o : frame length */
1094 : int16_t *pL_spec, /* o : length of the coded spectrum */
1095 : int16_t *ptcx_offset, /* o : folding point offset relative to the end of the previous frame */
1096 : int16_t *pnoiseFillingBorder, /* o : noise filling border */
1097 : float spectrum[], /* o : quantized MDCT spectrum */
1098 : CONTEXT_HM_CONFIG *hm_cfg, /* o : Context-based harmonic model configuration */
1099 : int16_t *hm_active, /* o : flag indicating if the harmonic model is active */
1100 : float lf_deemph_fact[], /* o : low frequency deemphasis factors */
1101 : int16_t *nf_seed, /* o : noise filling random seed */
1102 : float *ener, /* o : energy of the quantized spectrum */
1103 : float *gain_tcx, /* o : global gain */
1104 : int16_t prm[] /* o : tcx parameters */
1105 : )
1106 : {
1107 891395 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
1108 : int16_t i, L_frame, L_frameTCX, L_spec, tcx_offset;
1109 : int16_t noiseFillingBorder, LtpPitchLag, PeriodicityIndex;
1110 : float sqGain, gain_tcx_opt, RelativeScore;
1111 : int16_t lastnzCtxHm, lastnz;
1112 : int16_t stop;
1113 : int16_t nEncodedCtxHm, stopCtxHm, sqBitsCtxHm, Selector;
1114 : int16_t nEncoded, sqBits_noStop;
1115 : int16_t NumIndexBits, signaling_bits, sqTargetBits, sqBits, ctxHmBits, resQBits, resQTargetBits;
1116 : int16_t *prm_ltp, *prm_tns, *prm_hm, *prm_lastnz, *sqQ, *prm_target;
1117 : float att;
1118 : int32_t total_brate;
1119 :
1120 : /*-----------------------------------------------------------*
1121 : * Init *
1122 : *-----------------------------------------------------------*/
1123 :
1124 891395 : sqGain = 1.0f;
1125 891395 : resQTargetBits = 0;
1126 :
1127 891395 : NumIndexBits = 0;
1128 891395 : sqBits = 0;
1129 891395 : ctxHmBits = 0;
1130 891395 : resQBits = 0;
1131 891395 : prm_ltp = &prm[1 + NOISE_FILL_RANGES];
1132 891395 : prm_tns = prm_ltp + LTPSIZE;
1133 891395 : prm_hm = prm_tns + tnsSize;
1134 891395 : prm_lastnz = prm_hm + 2;
1135 891395 : sqQ = prm_hm + NPRM_CTX_HM;
1136 :
1137 891395 : total_brate = ( st->element_mode == IVAS_CPE_MDCT ) ? st->element_brate : st->total_brate;
1138 :
1139 : /*-----------------------------------------------------------*
1140 : * Init lengths *
1141 : *-----------------------------------------------------------*/
1142 :
1143 891395 : L_frame = st->L_frame;
1144 891395 : L_frameTCX = hTcxEnc->L_frameTCX;
1145 891395 : L_spec = st->hTcxCfg->tcx_coded_lines;
1146 891395 : tcx_offset = st->hTcxCfg->tcx_offset;
1147 :
1148 891395 : if ( st->core == TCX_10_CORE )
1149 : {
1150 33776 : L_frame /= 2;
1151 33776 : L_frameTCX /= 2;
1152 33776 : L_spec /= 2;
1153 : }
1154 857619 : else if ( st->last_core == ACELP_CORE )
1155 : {
1156 9376 : st->hTcxCfg->last_aldo = 0;
1157 :
1158 9376 : L_frame += tcx_offset;
1159 9376 : L_frameTCX += st->hTcxCfg->tcx_offsetFB;
1160 9376 : L_spec += st->hTcxCfg->tcx_coded_lines >> 2;
1161 :
1162 9376 : if ( st->hTcxCfg->lfacNext < 0 )
1163 : {
1164 9376 : L_frame -= st->hTcxCfg->lfacNext;
1165 9376 : L_frameTCX -= st->hTcxCfg->lfacNextFB;
1166 9376 : tcx_offset = st->hTcxCfg->lfacNext;
1167 : }
1168 : else
1169 : {
1170 0 : tcx_offset = 0;
1171 : }
1172 9376 : hTcxEnc->noiseLevelMemory_cnt = 0;
1173 : }
1174 :
1175 891395 : *pL_frameTCX = L_frameTCX;
1176 891395 : *pL_frame = L_frame;
1177 891395 : *pL_spec = L_spec;
1178 891395 : *ptcx_offset = tcx_offset;
1179 :
1180 : /* target bitrate for SQ */
1181 891395 : sqTargetBits = nb_bits - NBITS_TCX_GAIN - NBITS_NOISE_FILL_LEVEL;
1182 :
1183 891395 : if ( st->enablePlcWaveadjust )
1184 : {
1185 0 : st->Tonal_SideInfo = DecideTonalSideInfo( x_orig, ( st->core == TCX_20_CORE ) ? st->L_frame : st->L_frame / 2, st->hTcxCfg->SFM2 );
1186 : }
1187 :
1188 : /* Start with the pre-shaped spectrum*/
1189 891395 : mvr2r( x_orig, spectrum, L_spec );
1190 :
1191 : /*-----------------------------------------------------------*
1192 : * Bandwidth Limitation *
1193 : *-----------------------------------------------------------*/
1194 :
1195 891395 : noiseFillingBorder = L_spec;
1196 891395 : if ( st->igf )
1197 : {
1198 611995 : noiseFillingBorder = st->hIGFEnc->infoStartLine;
1199 : }
1200 891395 : *pnoiseFillingBorder = noiseFillingBorder;
1201 :
1202 891395 : if ( st->igf )
1203 : {
1204 91785435 : for ( i = st->hIGFEnc->infoStopLine; i < max( L_frame, L_frameTCX ); i++ )
1205 : {
1206 91173440 : spectrum[i] = 0.0f;
1207 : }
1208 : }
1209 : else
1210 : {
1211 15957000 : for ( i = noiseFillingBorder; i < max( L_frame, L_frameTCX ); i++ )
1212 : {
1213 15677600 : spectrum[i] = 0.0f;
1214 : }
1215 : }
1216 :
1217 : /*-----------------------------------------------------------*
1218 : * Quantization *
1219 : *-----------------------------------------------------------*/
1220 :
1221 891395 : if ( !hTcxEnc->tcx_lpc_shaped_ari )
1222 : {
1223 : /* context based arithmetic coder */
1224 :
1225 : /* initialize signaling to default, i.e. context based AC is inactive */
1226 873938 : prm_hm[0] = 0;
1227 873938 : prm_hm[1] = -1;
1228 :
1229 : /* Fast estimation of the scalar quantizer step size */
1230 873938 : if ( st->hTcxCfg->ctx_hm && st->last_core != ACELP_CORE )
1231 : {
1232 180775 : LtpPitchLag = ( ( !st->tcxonly ) && ( hTcxEnc->tcxltp_pitch_int < st->L_frame ) ? ( ( 2 * st->L_frame * st->pit_res_max ) << kLtpHmFractionalResolution ) / ( hTcxEnc->tcxltp_pitch_int * st->pit_res_max + hTcxEnc->tcxltp_pitch_fr ) : -1 );
1233 :
1234 180775 : ++ctxHmBits; /* ContextHM flag */
1235 180775 : --sqTargetBits; /* ContextHM flag */
1236 :
1237 180775 : PeriodicityIndex = SearchPeriodicityIndex( spectrum, NULL, L_spec, sqTargetBits, LtpPitchLag, hTcxEnc->tcxltp ? hTcxEnc->tcxltp_gain : -1.0f, &RelativeScore );
1238 :
1239 180775 : NumIndexBits = CountIndexBits( L_spec >= 256, PeriodicityIndex );
1240 :
1241 180775 : if ( st->element_mode > EVS_MONO )
1242 : {
1243 180167 : ConfigureContextHm( L_spec, sqTargetBits - NumIndexBits, PeriodicityIndex, LtpPitchLag, hm_cfg );
1244 : }
1245 : else
1246 : {
1247 608 : ConfigureContextHm( L_spec, sqTargetBits, PeriodicityIndex, LtpPitchLag, hm_cfg );
1248 : }
1249 :
1250 : /* Quantize original spectrum */
1251 180775 : sqGain = SQ_gain( spectrum, (int16_t) ( hTcxEnc->tcx_target_bits_fac * (float) sqTargetBits ), L_spec );
1252 :
1253 180775 : tcx_scalar_quantization( spectrum, sqQ, L_spec, sqGain, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly );
1254 :
1255 : /* Estimate original bitrate */
1256 180775 : stop = 0;
1257 180775 : if ( st->element_mode > EVS_MONO )
1258 : {
1259 180167 : sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, &lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL );
1260 : }
1261 : else
1262 : {
1263 608 : sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC( sqQ, L_spec, &lastnz, &nEncoded, sqTargetBits, &stop, NULL );
1264 : }
1265 :
1266 : /* Estimate context mapped bitrate */
1267 180775 : stopCtxHm = 0;
1268 :
1269 : /* Context Mapping */
1270 180775 : if ( st->element_mode > EVS_MONO )
1271 : {
1272 180167 : sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, 0, hm_cfg );
1273 : }
1274 : else
1275 : {
1276 608 : sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, hm_cfg );
1277 : }
1278 :
1279 : /* Decide whether or not to use context mapping */
1280 180775 : Selector = max( stop, sqBits ) - ( max( stopCtxHm, sqBitsCtxHm ) + NumIndexBits );
1281 :
1282 180775 : if ( Selector > 2 || ( abs( Selector ) <= 2 && kCtxHmOlRSThr < RelativeScore ) )
1283 : {
1284 : /* CtxHm is likely better */
1285 12775 : sqTargetBits -= NumIndexBits;
1286 12775 : ctxHmBits += NumIndexBits;
1287 12775 : prm_hm[0] = 1;
1288 12775 : prm_hm[1] = PeriodicityIndex;
1289 12775 : *prm_lastnz = lastnzCtxHm;
1290 12775 : sqBits_noStop = sqBits = sqBitsCtxHm;
1291 12775 : nEncoded = nEncodedCtxHm;
1292 12775 : stop = stopCtxHm;
1293 : }
1294 : else
1295 : {
1296 : /* Original is better or not much difference */
1297 168000 : prm_hm[0] = 0;
1298 168000 : prm_hm[1] = PeriodicityIndex;
1299 168000 : *prm_lastnz = lastnz;
1300 168000 : PeriodicityIndex = -1;
1301 :
1302 168000 : sqBits_noStop = sqBits;
1303 : }
1304 :
1305 180775 : if ( stop != 0 )
1306 : {
1307 66293 : sqBits = stop;
1308 : }
1309 : }
1310 : else
1311 : {
1312 : /* no context hm*/
1313 693163 : PeriodicityIndex = -1;
1314 :
1315 693163 : if ( st->element_mode == IVAS_CPE_MDCT )
1316 : {
1317 653460 : sqGain = SQ_gain_estimate( spectrum, (int16_t) ( hTcxEnc->tcx_target_bits_fac * (float) sqTargetBits ), L_spec );
1318 : }
1319 : else
1320 : {
1321 39703 : sqGain = SQ_gain( spectrum, (int16_t) ( hTcxEnc->tcx_target_bits_fac * (float) sqTargetBits ), L_spec );
1322 : }
1323 :
1324 : /* Quantize spectrum */
1325 693163 : tcx_scalar_quantization( spectrum, sqQ, L_spec, sqGain, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly );
1326 :
1327 : /* Estimate bitrate */
1328 693163 : stop = 0;
1329 693163 : if ( st->element_mode > EVS_MONO )
1330 : {
1331 693125 : sqBits_noStop = sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL );
1332 : }
1333 : else
1334 : {
1335 38 : sqBits_noStop = sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, NULL );
1336 : }
1337 :
1338 693163 : if ( stop != 0 )
1339 : {
1340 361084 : sqBits = stop;
1341 : }
1342 : } /* end of if (ctx_hm) */
1343 :
1344 : /* Adjust correction factor */
1345 873938 : if ( ( L_spec & ( L_spec - 1 ) ) == 0 )
1346 : {
1347 : /* power-of-2 */
1348 0 : hTcxEnc->tcx_target_bits_fac *= (float) sqTargetBits / (float) ( sqBits + 1 );
1349 : }
1350 : else
1351 : {
1352 873938 : hTcxEnc->tcx_target_bits_fac *= (float) sqTargetBits / (float) sqBits;
1353 : }
1354 :
1355 873938 : if ( hTcxEnc->tcx_target_bits_fac > 1.25 )
1356 : {
1357 88117 : hTcxEnc->tcx_target_bits_fac = 1.25;
1358 : }
1359 873938 : if ( hTcxEnc->tcx_target_bits_fac < 0.75 )
1360 : {
1361 56721 : hTcxEnc->tcx_target_bits_fac = 0.75;
1362 : }
1363 :
1364 : /* Refine quantizer step size with a rate-control-loop (optional) */
1365 873938 : sqBits = tcx_scalar_quantization_rateloop( spectrum, sqQ, L_spec, &sqGain, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, prm_lastnz, /* lastnz */ sqTargetBits, &nEncoded, &stop, sqBits_noStop, sqBits, st->hTcxCfg->tcxRateLoopOpt, st->tcxonly, PeriodicityIndex >= 0 ? hm_cfg : NULL, ( st->element_mode == IVAS_CPE_MDCT ? 2 : 4 ), st->element_mode );
1366 :
1367 873938 : if ( ctxHmBits > 0 )
1368 : {
1369 : /* Mapping tool is enabled */
1370 : /* Truncate spectrum */
1371 426314 : for ( i = nEncoded; i < L_spec; i++ )
1372 : {
1373 424194 : if ( st->element_mode > EVS_MONO )
1374 : {
1375 178655 : break;
1376 : }
1377 : else
1378 : {
1379 245539 : sqQ[i] = 0;
1380 : }
1381 : }
1382 :
1383 180775 : if ( PeriodicityIndex >= 0 )
1384 : {
1385 : /* Mapping is used */
1386 : /* Estimate non-mapped bitrate */
1387 12775 : stopCtxHm = 1;
1388 12775 : if ( st->element_mode > EVS_MONO )
1389 : {
1390 : /* Fix: Use updated value for target bits (sqTargetBits + NumIndexBits) before computing non-mapped estimate */
1391 12727 : sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, &lastnz, &nEncodedCtxHm, sqTargetBits + NumIndexBits, &stopCtxHm, 0, NULL );
1392 : }
1393 : else
1394 : {
1395 48 : sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC( sqQ, L_spec, &lastnz, &nEncodedCtxHm, sqTargetBits, &stopCtxHm, NULL );
1396 : }
1397 :
1398 : /* Decide whether or not to revert mapping */
1399 12775 : Selector = sqBits - ( sqBitsCtxHm + NumIndexBits );
1400 :
1401 12775 : if ( st->element_mode > EVS_MONO )
1402 : {
1403 12727 : if ( ( stopCtxHm == 0 && Selector > 0 ) || stop ) /* If overflow occured with mapped, select non-mapped */
1404 : {
1405 : /* Non-mapped is better */
1406 647 : sqTargetBits += NumIndexBits;
1407 647 : ctxHmBits -= NumIndexBits;
1408 647 : prm_hm[0] = 0;
1409 647 : *prm_lastnz = lastnz;
1410 647 : PeriodicityIndex = -1;
1411 647 : sqBits_noStop = sqBits = sqBitsCtxHm;
1412 647 : nEncoded = nEncodedCtxHm;
1413 647 : stop = stopCtxHm;
1414 : }
1415 : }
1416 : else
1417 : {
1418 48 : if ( stopCtxHm == 0 && Selector > 0 )
1419 : {
1420 : /* Non-mapped is better */
1421 0 : sqTargetBits += NumIndexBits;
1422 0 : ctxHmBits -= NumIndexBits;
1423 0 : prm_hm[0] = 0;
1424 0 : *prm_lastnz = lastnz;
1425 0 : PeriodicityIndex = -1;
1426 0 : sqBits_noStop = sqBits = sqBitsCtxHm;
1427 0 : nEncoded = nEncodedCtxHm;
1428 0 : stop = stopCtxHm;
1429 : }
1430 : }
1431 : }
1432 : else
1433 : {
1434 : /* Mapping is not used */
1435 168000 : if ( st->element_mode > EVS_MONO )
1436 : {
1437 : /* Truncate Spectrum */
1438 86860590 : for ( i = nEncoded; i < L_spec; i++ )
1439 : {
1440 86693150 : sqQ[i] = 0;
1441 : }
1442 : }
1443 : /* Estimate mapped bitrate */
1444 168000 : stopCtxHm = 1;
1445 168000 : if ( st->element_mode > EVS_MONO )
1446 : {
1447 167440 : sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, 0, hm_cfg );
1448 : }
1449 : else
1450 : {
1451 560 : sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, hm_cfg );
1452 : }
1453 :
1454 : /* Decide whether or not to use mapping */
1455 168000 : Selector = sqBits - ( sqBitsCtxHm + NumIndexBits );
1456 :
1457 168000 : if ( stopCtxHm == 0 && Selector > 0 )
1458 : {
1459 : /* Mapped is better */
1460 814 : sqTargetBits -= NumIndexBits;
1461 814 : ctxHmBits += NumIndexBits;
1462 814 : prm_hm[0] = 1;
1463 814 : *prm_lastnz = lastnzCtxHm;
1464 814 : PeriodicityIndex = prm_hm[1];
1465 814 : sqBits_noStop = sqBits = sqBitsCtxHm;
1466 814 : nEncoded = nEncodedCtxHm;
1467 814 : stop = stopCtxHm;
1468 : }
1469 : }
1470 : }
1471 :
1472 : /* Limit low sqGain for avoiding saturation of the gain quantizer*/
1473 873938 : if ( st->hTcxCfg->tcxRateLoopOpt < 3 && sqGain < sqrt( (float) NORM_MDCT_FACTOR / (float) L_spec ) )
1474 : {
1475 5981 : sqGain = (float) sqrt( (float) NORM_MDCT_FACTOR / (float) L_spec );
1476 :
1477 5981 : tcx_scalar_quantization( spectrum, sqQ, L_spec, sqGain, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly );
1478 :
1479 5981 : stop = 1;
1480 5981 : if ( st->element_mode > EVS_MONO )
1481 : {
1482 : /* Ensure non-mapped estimation is used for limiting low sqGain considering that this refinement occurs very rarely */
1483 5981 : PeriodicityIndex = -1;
1484 5981 : if ( prm_hm[0] == 1 )
1485 : {
1486 0 : prm_hm[0] = 0;
1487 0 : sqTargetBits += NumIndexBits;
1488 0 : ctxHmBits -= NumIndexBits;
1489 : }
1490 5981 : sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL );
1491 : }
1492 : else
1493 : {
1494 0 : sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, PeriodicityIndex >= 0 ? hm_cfg : NULL );
1495 : }
1496 : }
1497 :
1498 : /* Truncate spectrum (for CBR) */
1499 873938 : if ( stop )
1500 : {
1501 66060807 : for ( i = nEncoded; i < L_spec; i++ )
1502 : {
1503 65933388 : sqQ[i] = 0;
1504 : }
1505 : }
1506 :
1507 : /* Save quantized Values */
1508 873938 : *nf_seed = 0;
1509 709704098 : for ( i = 0; i < L_spec; i++ )
1510 : {
1511 708830160 : spectrum[i] = (float) sqQ[i];
1512 : /* noise filling seed */
1513 708830160 : *nf_seed += (int16_t) ( abs( sqQ[i] ) * i * 2 );
1514 : }
1515 : }
1516 : else
1517 : {
1518 : /* low rates: envelope based arithmetic coder */
1519 :
1520 17457 : AdaptLowFreqEmph( spectrum, NULL, 0.f, 1, gainlpc, L_frame );
1521 :
1522 17457 : prm_target = sqQ;
1523 17457 : sqQ = prm_target + 1;
1524 :
1525 17457 : LtpPitchLag = ( ( hTcxEnc->tcxltp_pitch_int < st->L_frame ) ? ( ( 2 * st->L_frame * st->pit_res_max ) << kLtpHmFractionalResolution ) / ( st->hTcxEnc->tcxltp_pitch_int * st->pit_res_max + hTcxEnc->tcxltp_pitch_fr ) : -1 );
1526 :
1527 17457 : tcx_arith_encode_envelope( spectrum, hm_cfg->indexBuffer, L_frame, L_spec, st, Aqind, sqTargetBits, sqQ, st->last_core != ACELP_CORE, prm_hm, /* HM parameter area */ LtpPitchLag, &sqBits, &signaling_bits, ( st->bwidth > WB ) ? 1 : 0 );
1528 :
1529 17457 : sqTargetBits -= signaling_bits;
1530 17457 : *prm_target = sqTargetBits;
1531 :
1532 : /* Noise filling seed */
1533 17457 : *nf_seed = 0;
1534 3654029 : for ( i = 0; i < noiseFillingBorder; ++i )
1535 : {
1536 3636572 : *nf_seed += (int16_t) ( abs( (int16_t) spectrum[i] ) * i * 2 );
1537 : }
1538 : }
1539 :
1540 891395 : *hm_active = prm_hm[0];
1541 :
1542 : /*-----------------------------------------------------------*
1543 : * Compute optimal TCX gain. *
1544 : *-----------------------------------------------------------*/
1545 :
1546 891395 : if ( lf_deemph_fact != NULL )
1547 : {
1548 : /* initialize LF deemphasis factors in lf_deemph_fact */
1549 198906335 : for ( i = 0; i < L_spec; i++ )
1550 : {
1551 198668400 : lf_deemph_fact[i] = 1.0f;
1552 : }
1553 : }
1554 :
1555 891395 : if ( !st->tcxonly )
1556 : {
1557 128960 : AdaptLowFreqDeemph( spectrum, hTcxEnc->tcx_lpc_shaped_ari, gainlpc, L_frame, lf_deemph_fact );
1558 : }
1559 :
1560 891395 : assert( x_orig != spectrum );
1561 891395 : gain_tcx_opt = get_gain( x_orig, spectrum, L_spec, ener );
1562 :
1563 891395 : if ( gain_tcx_opt <= 0.0f )
1564 : {
1565 2689 : gain_tcx_opt = sqGain;
1566 : }
1567 891395 : *gain_tcx = gain_tcx_opt;
1568 :
1569 891395 : if ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD )
1570 : {
1571 14475 : calculate_hangover_attenuation_gain( st, &att, vad_hover_flag );
1572 14475 : *gain_tcx *= att;
1573 : }
1574 :
1575 : /*-----------------------------------------------------------*
1576 : * Quantize TCX gain *
1577 : *-----------------------------------------------------------*/
1578 :
1579 : /* gain quantization here in case of VBR unvoiced coding; fixes problems of uninitialized global gain values */
1580 891395 : if ( total_brate >= ACELP_13k20 && !st->rf_mode )
1581 : {
1582 858266 : tcx_QuantizeGain( L_spec, gain_tcx, &prm[0] );
1583 : }
1584 :
1585 : /*-----------------------------------------------------------*
1586 : * Residual Quantization *
1587 : *-----------------------------------------------------------*/
1588 :
1589 891395 : if ( st->hTcxCfg->resq )
1590 : {
1591 393200 : resQTargetBits = sqTargetBits - sqBits;
1592 :
1593 393200 : if ( hTcxEnc->tcx_lpc_shaped_ari )
1594 : {
1595 : /* envelope based arithmetic coder */
1596 : int16_t *prm_resq;
1597 :
1598 17457 : prm_resq = sqQ + sqTargetBits - resQTargetBits;
1599 :
1600 17457 : resQBits = tcx_ari_res_Q_spec( x_orig, hm_cfg->indexBuffer, spectrum, L_spec, *gain_tcx, prm_resq, resQTargetBits, resQBits, st->hTcxCfg->sq_rounding, lf_deemph_fact );
1601 :
1602 : /* Transmit zeros when there bits remain after RESQ */
1603 18647 : for ( i = resQBits; i < resQTargetBits; ++i )
1604 : {
1605 1190 : prm_resq[i] = 0;
1606 : }
1607 : }
1608 : else
1609 : {
1610 : /* context based arithmetic coder */
1611 375743 : resQBits = tcx_res_Q_gain( gain_tcx_opt, gain_tcx, sqQ + L_spec, resQTargetBits );
1612 :
1613 375743 : resQBits = tcx_res_Q_spec( x_orig, spectrum, L_spec, *gain_tcx, sqQ + L_spec, resQTargetBits, resQBits, st->hTcxCfg->sq_rounding, st->tcxonly ? NULL : lf_deemph_fact );
1614 : }
1615 : }
1616 :
1617 : /*-----------------------------------------------------------*
1618 : * ALFE tcx only bitrates *
1619 : *-----------------------------------------------------------*/
1620 :
1621 891395 : if ( st->element_mode != IVAS_CPE_MDCT )
1622 : {
1623 237935 : if ( st->tcxonly )
1624 : {
1625 108975 : if ( hTcxEnc->tcxltp && ( hTcxEnc->tcxltp_gain > 0.0f ) && !hTcxEnc->fUseTns[frame_cnt] )
1626 : {
1627 3732 : PsychAdaptLowFreqDeemph( spectrum, gainlpc, NULL );
1628 : }
1629 : }
1630 : }
1631 :
1632 : #ifdef DEBUGGING
1633 : /*-----------------------------------------------------------*
1634 : * TCX SNR for Analysis purposes *
1635 : *-----------------------------------------------------------*/
1636 : {
1637 : float diff[N_MAX];
1638 : char name[50] = "TCX_output_chX ";
1639 :
1640 : for ( i = 0; i < min( L_frame, L_spec ); i++ )
1641 : {
1642 : diff[i] = x_orig[i] - *gain_tcx * spectrum[i];
1643 : }
1644 :
1645 : if ( st->id_element == 0 )
1646 : {
1647 : name[13] = (char) ( st->idchan + '0' );
1648 : }
1649 : else
1650 : {
1651 : char name2[50] = "TCX_output.idX_chX ";
1652 : name2[13] = (char) ( st->id_element + '0' );
1653 : name2[17] = (char) ( st->idchan + '0' );
1654 : strcpy( name, name2 );
1655 : }
1656 :
1657 : snr( x_orig, diff, min( L_frame, L_spec ), name );
1658 : }
1659 : #endif
1660 :
1661 891395 : return;
1662 : }
1663 :
1664 :
1665 : /*-------------------------------------------------------------------*
1666 : * InternalTCXDecoder()
1667 : *
1668 : *
1669 : *-------------------------------------------------------------------*/
1670 :
1671 237935 : void InternalTCXDecoder(
1672 : Encoder_State *st, /* i/o: state handle */
1673 : const int16_t frame_cnt, /* i : frame counter in the super_frame */
1674 : const int16_t L_frameTCX, /* i : full frame length */
1675 : const int16_t L_frame, /* i : frame length */
1676 : const int16_t L_spec, /* i : length of the coded spectrum */
1677 : const int16_t tcx_offset, /* i : folding point offset relative to the end of the previous frame */
1678 : const int16_t noiseFillingBorder, /* i : noise filling border */
1679 : const float *x_quant, /* i : quantized spectrum */
1680 : const float ener, /* i : energy of the quantized spectrum */
1681 : float lf_deemph_fact[], /* i/o: low frequency deemphasis factors */
1682 : const float fac_ns, /* i : noise filling level */
1683 : const int16_t nf_seed, /* i : noise filling random seed */
1684 : const float *A, /* i : LPC representation of the FDNS gains */
1685 : float *gainlpc, /* i/o: FDNS gains */
1686 : const int16_t hm_active, /* i : flag indicating if the harmonic model is active */
1687 : float gain_tcx, /* i/o: global gain / quantized global gain */
1688 : float spectrum[], /* o : dequantized spectrum */
1689 : float synth[], /* o : time domain signal */
1690 : int16_t *gain_tcx_q /* o : quantized global gain (at low bitrates) */
1691 : )
1692 : {
1693 237935 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
1694 : int16_t i, iStart, noiseTransWidth;
1695 : int16_t tcx_last_overlap_mode, overlap;
1696 : int16_t nz; /* non-zero length in ALDO window*/
1697 : int16_t aldo; /* ALDO flag in current frame*/
1698 : float xn_buf[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX];
1699 : float Aq_old[M + 1];
1700 : float sns_interpolated_scalefactors[FDNS_NPTS];
1701 :
1702 237935 : mvr2r( x_quant, spectrum, max( L_frame, L_spec ) );
1703 :
1704 : /* Replication of ACELP formant enhancement for low rates */
1705 237935 : if ( st->total_brate < ACELP_13k20 || st->rf_mode )
1706 : {
1707 33129 : tcxFormantEnhancement( lf_deemph_fact, gainlpc, spectrum, L_frame );
1708 : }
1709 :
1710 : /*-----------------------------------------------------------*
1711 : * Noise Filling. *
1712 : *-----------------------------------------------------------*/
1713 :
1714 237935 : if ( fac_ns > 0.0f )
1715 : {
1716 219324 : iStart = tcxGetNoiseFillingTilt( A, L_frame, ( st->total_brate >= ACELP_13k20 && !st->rf_mode ), &hTcxEnc->noiseTiltFactor );
1717 :
1718 219324 : noiseTransWidth = GetTransWidth( st->tcxonly, ( L_frame == st->L_frame >> 1 ), hTcxEnc->tcxltp_gain, ( st->hTcxCfg->ctx_hm && st->last_core != ACELP_CORE && hm_active ) );
1719 219324 : assert( st->element_mode != IVAS_CPE_MDCT );
1720 219324 : tcx_noise_filling( spectrum, nf_seed, iStart, noiseFillingBorder, noiseTransWidth, L_frame, hTcxEnc->noiseTiltFactor, fac_ns, NULL, st->element_mode );
1721 : }
1722 :
1723 237935 : if ( st->total_brate < ACELP_13k20 || st->rf_mode )
1724 : {
1725 : /* partially recompute global gain (energy part), taking noise filling and formant enhancement into account */
1726 33129 : float ener_nf = 1e-6f;
1727 21344489 : for ( i = 0; i < L_spec; i++ )
1728 : {
1729 21311360 : ener_nf += spectrum[i] * spectrum[i];
1730 : }
1731 33129 : gain_tcx *= (float) sqrt( ener / ener_nf );
1732 33129 : tcx_QuantizeGain( L_spec, &gain_tcx, gain_tcx_q );
1733 : }
1734 :
1735 : /*end of noise filling*/
1736 :
1737 : /*-----------------------------------------------------------*
1738 : * Noise shaping in frequency domain (1/Wz) *
1739 : *-----------------------------------------------------------*/
1740 :
1741 237935 : if ( st->element_mode == IVAS_CPE_MDCT )
1742 : {
1743 0 : sns_interpolate_scalefactors( sns_interpolated_scalefactors, A, DEC );
1744 0 : sns_shape_spectrum( spectrum, st->hTcxCfg->psychParamsCurrent, sns_interpolated_scalefactors, L_frame );
1745 : }
1746 : else
1747 : {
1748 237935 : mdct_noiseShaping( spectrum, L_frame, gainlpc, FDNS_NPTS );
1749 : }
1750 :
1751 : /*-----------------------------------------------------------*
1752 : * Apply gain *
1753 : *-----------------------------------------------------------*/
1754 :
1755 237935 : if ( st->hTcxCfg->coder_type == INACTIVE )
1756 : {
1757 :
1758 13536 : gain_tcx *= st->hTcxCfg->na_scale;
1759 : }
1760 :
1761 237935 : v_multc( spectrum, gain_tcx, spectrum, L_spec );
1762 :
1763 237935 : tcx_last_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */
1764 :
1765 237935 : if ( ( L_frame == st->L_frame >> 1 ) && st->tcxonly )
1766 : {
1767 4154 : int16_t L = L_frame;
1768 :
1769 4154 : if ( ( st->hTcxCfg->fIsTNSAllowed && hTcxEnc->fUseTns[frame_cnt] != 0 ) || ( L_spec > L_frame ) )
1770 : {
1771 4052 : L = L_spec;
1772 : }
1773 :
1774 4154 : tcxInvertWindowGrouping( st->hTcxCfg, xn_buf, spectrum, L, hTcxEnc->fUseTns[frame_cnt], st->last_core, tcx_last_overlap_mode, frame_cnt, 0 );
1775 : }
1776 :
1777 : /*-----------------------------------------------------------*
1778 : * Temporal Noise Shaping Synthesis *
1779 : *-----------------------------------------------------------*/
1780 :
1781 237935 : if ( st->hTcxCfg->fIsTNSAllowed )
1782 : {
1783 161953 : SetTnsConfig( st->hTcxCfg, st->core == TCX_20_CORE, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) );
1784 :
1785 : /* Apply TNS to get the reconstructed signal */
1786 161953 : if ( hTcxEnc->fUseTns[frame_cnt] != 0 )
1787 : {
1788 17665 : ApplyTnsFilter( st->hTcxCfg->pCurrentTnsConfig, &hTcxEnc->tnsData[frame_cnt], spectrum, 0 );
1789 :
1790 17665 : if ( ( L_frame == st->L_frame >> 1 ) && ( st->tcxonly ) )
1791 : {
1792 2400 : if ( ( st->hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) ||
1793 1185 : ( ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( tcx_last_overlap_mode == 0 ) ) )
1794 : {
1795 1749 : const int16_t L_win = L_spec >> 1;
1796 :
1797 : /* undo rearrangement of LF sub-window lines for TNS synthesis filter */
1798 1749 : if ( L_frame > L_spec )
1799 : {
1800 0 : assert( 0 );
1801 : }
1802 : else
1803 : {
1804 1749 : mvr2r( spectrum + 8, xn_buf, L_win );
1805 1749 : mvr2r( xn_buf, spectrum + L_win, 8 );
1806 1749 : mvr2r( xn_buf + 8, spectrum + 8, L_win - 8 );
1807 : }
1808 : }
1809 : }
1810 : }
1811 : }
1812 :
1813 : /*-----------------------------------------------------------*
1814 : * Compute inverse MDCT of spectrum[]. *
1815 : *-----------------------------------------------------------*/
1816 :
1817 237935 : lsp2a_stab( st->lsp_old, Aq_old, M );
1818 237935 : overlap = st->hTcxCfg->tcx_mdct_window_length;
1819 237935 : nz = NS2SA( st->sr_core, N_ZERO_MDCT_NS );
1820 237935 : aldo = 0;
1821 :
1822 237935 : if ( ( L_frame == st->L_frame >> 1 ) && ( st->tcxonly ) )
1823 : {
1824 4154 : if ( st->hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP )
1825 : {
1826 : /* minimum or half overlap, two transforms, grouping into one window */
1827 : float win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
1828 1633 : const int16_t L_win = L_frame >> 1;
1829 1633 : const int16_t L_spec_TCX5 = max( L_frame, L_spec ) >> 1;
1830 1633 : const int16_t L_ola = ( st->hTcxCfg->tcx_last_overlap_mode == MIN_OVERLAP ) ? st->hTcxCfg->tcx_mdct_window_min_length : st->hTcxCfg->tcx_mdct_window_half_length;
1831 : int16_t w;
1832 :
1833 1633 : set_f( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
1834 1633 : set_zero( xn_buf, tcx_offset + ( L_ola >> 1 ) ); /* zero left end of buffer */
1835 :
1836 4899 : for ( w = 0; w < 2; w++ )
1837 : {
1838 3266 : if ( st->hTcxCfg->tcx_last_overlap_mode == MIN_OVERLAP )
1839 : {
1840 1540 : TCX_MDCT_Inverse( spectrum + w * L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode );
1841 : }
1842 : else
1843 : {
1844 1726 : TCX_MDCT_Inverse( spectrum + w * L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode );
1845 : }
1846 :
1847 3266 : tcx_windowing_synthesis_current_frame( win, st->hTcxCfg->tcx_aldo_window_2, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, L_ola, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, w == 0 && st->last_core == ACELP_CORE, ( w > 0 ) || ( w == 0 && tcx_last_overlap_mode == 2 ) ? MIN_OVERLAP : st->hTcxCfg->tcx_last_overlap_mode, st->hTcxEnc->acelp_zir, st->hTcxEnc->Txnq, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans, L_win, tcx_offset < 0 ? -tcx_offset : 0, ( w > 0 ) ? 1 : st->last_core, 0, 0 );
1848 :
1849 3266 : if ( w > 0 )
1850 : {
1851 1633 : tcx_windowing_synthesis_past_frame( xn_buf + tcx_offset - ( L_ola >> 1 ) + w * L_win, st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, L_ola, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, 2 );
1852 : }
1853 :
1854 : /* add part of current sub-window overlapping with previous window */
1855 3266 : v_add( win, xn_buf + tcx_offset - ( L_ola >> 1 ) + w * L_win, xn_buf + tcx_offset - ( L_ola >> 1 ) + w * L_win, L_ola );
1856 :
1857 : /* copy new sub-window region not overlapping with previous window */
1858 3266 : mvr2r( win + L_ola, xn_buf + tcx_offset + ( L_ola >> 1 ) + w * L_win, L_win );
1859 : }
1860 :
1861 : /* To assure that no garbage values are copied to Txnq */
1862 1633 : set_zero( xn_buf + L_frame + tcx_offset + ( L_ola >> 1 ), overlap - tcx_offset - ( L_ola >> 1 ) );
1863 : }
1864 2521 : else if ( ( frame_cnt == 0 ) && ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) )
1865 598 : {
1866 : /* special overlap attempt, two transforms, grouping into one window */
1867 : float win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
1868 598 : const int16_t L_win = L_frame >> 1;
1869 598 : const int16_t L_spec_TCX5 = max( L_frame, L_spec ) >> 1;
1870 598 : const int16_t L_ola = st->hTcxCfg->tcx_mdct_window_min_length;
1871 : int16_t w;
1872 :
1873 598 : set_f( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
1874 :
1875 : /* Resize overlap (affect only asymmetric window)*/
1876 598 : overlap = st->hTcxCfg->tcx_mdct_window_delay;
1877 :
1878 : /* 1st TCX-5 window, special MDCT with minimum overlap on right side */
1879 598 : TCX_MDCT_Inverse( spectrum, win + L_win, 0, L_win - ( L_ola >> 1 ), L_ola, st->element_mode );
1880 :
1881 : /* copy new sub-window region not overlapping with previous window */
1882 598 : mvr2r( win + L_win, xn_buf + ( overlap >> 1 ), L_win + ( L_ola >> 1 ) );
1883 :
1884 : /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */
1885 598 : TCX_MDCT_Inverse( spectrum + L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode );
1886 :
1887 598 : tcx_windowing_synthesis_current_frame( win, st->hTcxCfg->tcx_aldo_window_2, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, L_ola, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, 0, /* left_rect */
1888 598 : 2, /* left_mode */ st->hTcxEnc->acelp_zir, st->hTcxEnc->Txnq, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans, L_win, tcx_offset < 0 ? -tcx_offset : 0, 1, /* not st->last_core */ 0, 0 );
1889 :
1890 598 : tcx_windowing_synthesis_past_frame( xn_buf + ( overlap >> 1 ) + L_win - ( L_ola >> 1 ), st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, L_ola, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, 2 );
1891 :
1892 : /* add part of current sub-window overlapping with previous window */
1893 598 : v_add( win, xn_buf + ( overlap >> 1 ) + L_win - ( L_ola >> 1 ), xn_buf + ( overlap >> 1 ) + L_win - ( L_ola >> 1 ), L_ola );
1894 :
1895 : /* copy new sub-window region not overlapping with previous window */
1896 598 : mvr2r( win + L_ola, xn_buf + ( overlap >> 1 ) + L_win + ( L_ola >> 1 ), L_win );
1897 :
1898 : /* extra folding-out on left side of win, for perfect reconstruction */
1899 83898 : for ( w = ( overlap >> 1 ); w < overlap; w++ )
1900 : {
1901 83300 : xn_buf[overlap - 1 - w] = -1.0f * xn_buf[w];
1902 : }
1903 :
1904 598 : tcx_windowing_synthesis_current_frame( xn_buf, st->hTcxCfg->tcx_aldo_window_2, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, 0, /* left_mode */ st->hTcxEnc->acelp_zir, st->hTcxEnc->Txnq, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans, L_win, tcx_offset < 0 ? -tcx_offset : 0, st->last_core, 0, 0 );
1905 : }
1906 : else
1907 : {
1908 : /* default, i.e. maximum overlap, single transform, no grouping */
1909 1923 : TCX_MDCT_Inverse( spectrum, xn_buf, overlap, L_frame - overlap, overlap, st->element_mode );
1910 :
1911 1923 : tcx_windowing_synthesis_current_frame( xn_buf, st->hTcxCfg->tcx_aldo_window_2, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, ( frame_cnt > 0 ) && ( tcx_last_overlap_mode == 0 ) && ( st->last_core != ACELP_CORE ) ? 2 : tcx_last_overlap_mode, st->hTcxEnc->acelp_zir, st->hTcxEnc->Txnq, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans, st->L_frame >> 2, tcx_offset < 0 ? -tcx_offset : 0, st->last_core, 0, 0 );
1912 :
1913 : } /* tcx_last_overlap_mode != FULL_OVERLAP */
1914 : }
1915 : else
1916 : {
1917 : /* frame is TCX-20 or not TCX-only */
1918 233781 : if ( st->hTcxCfg->tcx_last_overlap_mode != TRANSITION_OVERLAP )
1919 : {
1920 : float tmp[L_FRAME_PLUS];
1921 :
1922 225793 : edct( spectrum, xn_buf + overlap / 2 + nz, L_frame, st->element_mode );
1923 :
1924 225793 : v_multc( xn_buf + overlap / 2 + nz, (float) sqrt( (float) L_frame / NORM_MDCT_FACTOR ), tmp, L_frame );
1925 :
1926 225793 : window_ola( tmp, xn_buf, st->hTcxEnc->old_out, L_frame, st->hTcxCfg->tcx_last_overlap_mode, st->hTcxCfg->tcx_curr_overlap_mode, 0, 0, NULL );
1927 225793 : aldo = 1;
1928 : }
1929 : else
1930 : {
1931 7988 : TCX_MDCT_Inverse( spectrum, xn_buf, overlap, L_frame - overlap, overlap, st->element_mode );
1932 :
1933 : /* Windowing, overlap and add */
1934 : /* Window current frame */
1935 7988 : tcx_windowing_synthesis_current_frame( xn_buf, st->hTcxCfg->tcx_aldo_window_2, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, st->hTcxCfg->tcx_last_overlap_mode, /*left mode*/ st->hTcxEnc->acelp_zir, st->hTcxEnc->Txnq, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans, st->L_frame >> 1, tcx_offset < 0 ? -tcx_offset : 0, st->last_core, 0, 0 );
1936 : }
1937 : } /* TCX-20/TCX-10 and TCX-only */
1938 :
1939 : /* Window and overlap-add past frame if past frame is TCX */
1940 237935 : if ( st->last_core > ACELP_CORE && ( ( ( L_frameTCX == hTcxEnc->L_frameTCX >> 1 ) && ( st->tcxonly ) ) || ( st->hTcxCfg->tcx_last_overlap_mode == TRANSITION_OVERLAP ) ) )
1941 : {
1942 4154 : if ( st->hTcxCfg->last_aldo )
1943 : {
1944 462004 : for ( i = 0; i < overlap - st->hTcxCfg->tcx_mdct_window_min_length; i++ )
1945 : {
1946 460080 : xn_buf[i] += st->hTcxEnc->old_out[i + nz];
1947 : }
1948 : /* fade truncated ALDO window */
1949 78604 : for ( ; i < overlap; i++ )
1950 : {
1951 76680 : xn_buf[i] += st->hTcxEnc->old_out[i + nz] * st->hTcxCfg->tcx_mdct_window_minimum[overlap - 1 - i];
1952 : }
1953 : }
1954 : else
1955 : {
1956 2230 : if ( frame_cnt > 0 && tcx_last_overlap_mode == 0 && st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP && st->last_core != ACELP_CORE )
1957 : {
1958 598 : tcx_last_overlap_mode = 2; /* use minimum overlap between the two TCX-10 windows */
1959 : }
1960 :
1961 2230 : tcx_windowing_synthesis_past_frame( st->hTcxEnc->Txnq, st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, ( tcx_last_overlap_mode == 0 || st->hTcxCfg->tcx_last_overlap_mode == MIN_OVERLAP ) ? st->hTcxCfg->tcx_last_overlap_mode : tcx_last_overlap_mode );
1962 :
1963 624670 : for ( i = 0; i < overlap; i++ )
1964 : {
1965 622440 : xn_buf[i] += st->hTcxEnc->Txnq[i];
1966 : }
1967 : }
1968 : }
1969 :
1970 237935 : if ( !aldo && ( ( ( L_frameTCX == hTcxEnc->L_frameTCX >> 1 ) && frame_cnt > 0 ) || L_frameTCX != ( hTcxEnc->L_frameTCX >> 1 ) ) )
1971 : {
1972 : /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/
1973 10065 : mvr2r( xn_buf + L_frame - nz, st->hTcxEnc->old_out, nz + overlap );
1974 10065 : set_zero( st->hTcxEnc->old_out + nz + overlap, nz );
1975 :
1976 10065 : tcx_windowing_synthesis_past_frame( st->hTcxEnc->old_out + nz, st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->hTcxCfg->tcx_curr_overlap_mode );
1977 :
1978 10065 : if ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP )
1979 : {
1980 867677 : for ( i = 0; i < nz; i++ )
1981 : {
1982 858708 : st->hTcxEnc->old_out[nz + overlap + i] = xn_buf[L_frame - 1 - i] * st->hTcxCfg->tcx_aldo_window_1_trunc[-1 - i];
1983 : }
1984 : }
1985 : }
1986 :
1987 237935 : st->hTcxCfg->last_aldo = aldo;
1988 :
1989 : /* Update Txnq */
1990 237935 : if ( !st->hTcxCfg->last_aldo )
1991 : {
1992 12142 : mvr2r( xn_buf + L_frame, st->hTcxEnc->Txnq, overlap );
1993 : }
1994 :
1995 : /* Output */
1996 237935 : mvr2r( xn_buf + ( overlap >> 1 ) - tcx_offset, synth, ( st->core == TCX_20_CORE ) ? st->L_frame : L_frame );
1997 :
1998 237935 : return;
1999 : }
2000 :
2001 : /*-------------------------------------------------------------------*
2002 : * QuantizeSpectrum()
2003 : *
2004 : *
2005 : *-------------------------------------------------------------------*/
2006 :
2007 237935 : void QuantizeSpectrum(
2008 : Encoder_State *st, /* i/o: encoder state structure */
2009 : const float A[], /* i : quantized coefficients NxAz_q[M+1] */
2010 : const Word16 Aqind[], /* i : frame-independent quantized coefficients (M+1) */
2011 : float gainlpc[], /* i : MDCT gains of the previous frame */
2012 : float synth[], /* o : synthesis buffer */
2013 : const int16_t nb_bits, /* i : bit budget */
2014 : const int16_t tnsSize, /* i : number of tns parameters put into prm */
2015 : int16_t prm[], /* o : tcx parameters */
2016 : const int16_t frame_cnt, /* i : frame counter in the super_frame */
2017 : CONTEXT_HM_CONFIG *hm_cfg, /* i : HM configuration */
2018 : const int16_t vad_hover_flag /* i : VAD hangover flag */
2019 : )
2020 : {
2021 : int16_t L_frameTCX; /* full frame length */
2022 : int16_t L_frame; /* frame length */
2023 : int16_t L_spec; /* length of the coded spectrum */
2024 : int16_t tcx_offset; /* folding point offset relative to the end of the previous frame */
2025 : int16_t noiseFillingBorder; /* noise filling border */
2026 : float quantized_spectrum[N_MAX]; /* quantized MDCT spectrum */
2027 : float lf_deemph_fact[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; /* low frequency deemphasis factors */
2028 : int16_t hm_active; /* flag indicating if the harmonic model is active */
2029 : float fac_ns; /* noise filling level */
2030 : int16_t nf_seed; /* noise filling random seed */
2031 : float ener; /* energy of the quantized spectrum */
2032 : float gain_tcx; /* global gain */
2033 237935 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
2034 :
2035 : /*-----------------------------------------------------------*
2036 : * Quantize the MDCT spectrum *
2037 : *-----------------------------------------------------------*/
2038 :
2039 237935 : QuantizeTCXSpectrum( st, frame_cnt, hTcxEnc->spectrum[frame_cnt], gainlpc, Aqind, tnsSize, nb_bits, vad_hover_flag,
2040 : &L_frameTCX, &L_frame, &L_spec, &tcx_offset, &noiseFillingBorder, quantized_spectrum, hm_cfg, &hm_active, lf_deemph_fact, &nf_seed, &ener, &gain_tcx, prm );
2041 :
2042 : /*-----------------------------------------------------------*
2043 : * Estimate and quantize noise factor *
2044 : *-----------------------------------------------------------*/
2045 :
2046 237935 : EstimateTCXNoiseLevel( st, hTcxEnc->spectrum[frame_cnt], quantized_spectrum, gain_tcx, L_frame, noiseFillingBorder, hm_active, &fac_ns, &prm[1] );
2047 :
2048 : /*-----------------------------------------------------------*
2049 : * Internal decoder *
2050 : *-----------------------------------------------------------*/
2051 :
2052 237935 : InternalTCXDecoder( st, frame_cnt, L_frameTCX, L_frame, L_spec, tcx_offset, noiseFillingBorder, quantized_spectrum, ener, lf_deemph_fact, fac_ns, nf_seed, A, gainlpc, hm_active, gain_tcx, hTcxEnc->spectrum[frame_cnt], synth, &prm[0] );
2053 :
2054 : /* Update L_frame_past */
2055 237935 : st->L_frame_past = L_frame;
2056 :
2057 : /* Update overlap */
2058 237935 : if ( ( ( ( L_frameTCX == hTcxEnc->L_frameTCX >> 1 ) && frame_cnt > 0 ) || ( st->hTcxCfg->tcx_last_overlap_mode == TRANSITION_OVERLAP ) ) && ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) )
2059 : {
2060 8969 : st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW;
2061 : }
2062 :
2063 :
2064 237935 : return;
2065 : }
2066 :
2067 :
2068 : /*-------------------------------------------------------------------*
2069 : * coder_tcx()
2070 : *
2071 : *
2072 : *-------------------------------------------------------------------*/
2073 :
2074 646 : void coder_tcx(
2075 : Encoder_State *st, /* i/o: encoder state structure */
2076 : TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */
2077 : const float A[], /* i : quantized coefficients NxAz_q[M+1] */
2078 : const Word16 Aqind[], /* i : frame-independent quantized coefficients (M+1) */
2079 : float synth[], /* o : decoded synthesis */
2080 : const int16_t L_frame_glob, /* i : frame length */
2081 : const int16_t L_frameTCX_glob,
2082 : const int16_t L_spec,
2083 : int16_t nb_bits, /* i : bit budget */
2084 : float spectrum[], /* i/o: MDCT spectrum */
2085 : int16_t prm[], /* o : tcx parameters */
2086 : CONTEXT_HM_CONFIG *hm_cfg,
2087 : const int16_t vad_hover_flag /* i : VAD hangover flag */
2088 : )
2089 : {
2090 : int16_t L_frame;
2091 646 : int16_t left_overlap = -1, right_overlap = -1;
2092 646 : int16_t tnsSize = 0; /* number of tns parameters put into prm */
2093 646 : int16_t tnsBits = 0; /* number of tns bits in the frame */
2094 646 : int16_t ltpBits = 0;
2095 : float gainlpc[FDNS_NPTS];
2096 : float buf[N_MAX + L_MDCT_OVLP_MAX];
2097 : float winMDST[N_MAX + L_MDCT_OVLP_MAX];
2098 : float *win;
2099 : float *powerSpec;
2100 646 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
2101 :
2102 646 : powerSpec = win = buf; /* Share memory for windowed TD signal and for the power spectrum */
2103 :
2104 646 : L_frame = L_frameTCX_glob;
2105 :
2106 : /*-----------------------------------------------------------*
2107 : * Windowing and MDCT *
2108 : *-----------------------------------------------------------*/
2109 :
2110 646 : if ( st->hTcxCfg->tcx_last_overlap_mode == TRANSITION_OVERLAP )
2111 : {
2112 38 : WindowSignal( hTcxCfg, hTcxCfg->tcx_offsetFB, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, &left_overlap, &right_overlap, st->hTcxEnc->speech_TCX, &L_frame, win, 1, 1 );
2113 :
2114 : /* Compute MDCT for xn_buf[] */
2115 38 : TCX_MDCT( win, spectrum, left_overlap, L_frame - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode );
2116 : }
2117 : else
2118 : {
2119 608 : wtda( st->hTcxEnc->new_speech_TCX, win, NULL, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, L_frame );
2120 :
2121 608 : WindowSignal( hTcxCfg, hTcxCfg->tcx_offsetFB, hTcxCfg->tcx_last_overlap_mode == ALDO_WINDOW ? FULL_OVERLAP : hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode == ALDO_WINDOW ? FULL_OVERLAP : hTcxCfg->tcx_curr_overlap_mode, &left_overlap, &right_overlap, st->hTcxEnc->speech_TCX, &L_frame, winMDST, 1, 1 );
2122 :
2123 608 : edct( win, spectrum, L_frame, st->element_mode );
2124 :
2125 608 : v_multc( spectrum, (float) sqrt( (float) NORM_MDCT_FACTOR / L_frame ), spectrum, L_frame );
2126 : }
2127 :
2128 : /*-----------------------------------------------------------*
2129 : * Attenuate upper end of NB spectrum, *
2130 : * to simulate ACELP behavior *
2131 : *-----------------------------------------------------------*/
2132 :
2133 646 : if ( st->narrowBand )
2134 : {
2135 0 : attenuateNbSpectrum( L_frame, spectrum );
2136 : }
2137 :
2138 : /*-----------------------------------------------------------*
2139 : * Compute noise-measure flags for spectrum filling *
2140 : * and quantization (0: tonal, 1: noise-like). *
2141 : * Detect low pass if present. *
2142 : *-----------------------------------------------------------*/
2143 :
2144 646 : AnalyzePowerSpectrum( st, L_frame * st->L_frame / hTcxEnc->L_frameTCX, L_frame, left_overlap, right_overlap, spectrum, ( st->hTcxCfg->tcx_last_overlap_mode == TRANSITION_OVERLAP ) ? win : winMDST, powerSpec );
2145 :
2146 646 : if ( hTcxCfg->fIsTNSAllowed )
2147 : {
2148 371 : SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, st->last_core == ACELP_CORE );
2149 :
2150 371 : TNSAnalysis( hTcxCfg, L_frame, L_spec, TCX_20, st->last_core == ACELP_CORE, spectrum, NULL, -1, hTcxEnc->tnsData, hTcxEnc->fUseTns, &st->hIGFEnc->tns_predictionGain );
2151 : }
2152 : else
2153 : {
2154 275 : hTcxEnc->fUseTns[0] = hTcxEnc->fUseTns[1] = 0;
2155 : }
2156 :
2157 646 : if ( st->igf )
2158 : {
2159 646 : ProcessIGF( st, spectrum, spectrum, powerSpec, 1, 0, 0, vad_hover_flag );
2160 : }
2161 :
2162 646 : ShapeSpectrum( hTcxCfg, A, gainlpc, L_frame_glob, L_spec, spectrum, hTcxEnc->fUseTns[0], st, NULL );
2163 :
2164 646 : if ( st->igf )
2165 : {
2166 646 : nb_bits -= st->hIGFEnc->infoTotalBitsPerFrameWritten;
2167 : }
2168 :
2169 646 : if ( hTcxCfg->fIsTNSAllowed )
2170 : {
2171 371 : EncodeTnsData( hTcxCfg->pCurrentTnsConfig, hTcxEnc->tnsData, prm + 1 + NOISE_FILL_RANGES + LTPSIZE, &tnsSize, &tnsBits );
2172 : }
2173 :
2174 646 : QuantizeSpectrum( st, A, Aqind, gainlpc, synth, nb_bits - tnsBits - ltpBits, tnsSize, prm, 0, hm_cfg, vad_hover_flag );
2175 :
2176 646 : return;
2177 : }
2178 :
2179 : /*-------------------------------------------------------------------*
2180 : * coder_tcx_post()
2181 : *
2182 : *
2183 : *-------------------------------------------------------------------*/
2184 :
2185 235858 : void coder_tcx_post(
2186 : Encoder_State *st, /* i/o: encoder memory state */
2187 : float *A, /* o : Quantized LPC coefficients */
2188 : const float *Ai /* i : Unquantized (interpolated) LPC coefficients */
2189 : )
2190 : {
2191 : float xn_buf[L_FRAME_MAX];
2192 :
2193 : /* TCX output */
2194 235858 : mvr2r( st->synth, xn_buf, st->L_frame );
2195 :
2196 : /*-----------------------------------------------------------*
2197 : * Memory update *
2198 : *-----------------------------------------------------------*/
2199 :
2200 : /* Update LPDmem (Txnq,syn,syn_pe,old_exc,wsyn,Ai,Aq) */
2201 235858 : tcx_encoder_memory_update( st, xn_buf, Ai, A );
2202 :
2203 235858 : return;
2204 : }
|