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