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