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