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 "cnst.h"
38 : #include "ivas_cnst.h"
39 : #include <assert.h>
40 : #include <stdint.h>
41 : #include "options.h"
42 : #ifdef DEBUGGING
43 : #include "debug.h"
44 : #endif
45 : #include <math.h>
46 : #include "rom_enc.h"
47 : #include "rom_com.h"
48 : #include "ivas_rom_com.h"
49 : #include "prot.h"
50 : #include "ivas_prot.h"
51 : #include "stat_enc.h"
52 : #include "wmc_auto.h"
53 :
54 : /*-------------------------------------------------------------------*
55 : * createFdCngEnc()
56 : *
57 : *
58 : *-------------------------------------------------------------------*/
59 :
60 1930 : ivas_error createFdCngEnc(
61 : HANDLE_FD_CNG_ENC *hFdCngEnc /* i/o: FD_CNG structure */
62 : )
63 : {
64 : HANDLE_FD_CNG_ENC hs;
65 : ivas_error error;
66 1930 : error = IVAS_ERR_OK;
67 :
68 : /* Set output to NULL in case of errors and early return */
69 1930 : *hFdCngEnc = NULL;
70 :
71 : /* Allocate memory */
72 1930 : if ( ( hs = (HANDLE_FD_CNG_ENC) malloc( sizeof( FD_CNG_ENC ) ) ) == NULL )
73 : {
74 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FD CNG ENC structure" );
75 : }
76 :
77 1930 : if ( ( error = createFdCngCom( &( hs->hFdCngCom ) ) ) != IVAS_ERR_OK )
78 : {
79 0 : return error;
80 : }
81 :
82 1930 : *hFdCngEnc = hs;
83 :
84 1930 : return error;
85 : }
86 :
87 : /*-------------------------------------------------------------------*
88 : * initFdCngEnc()
89 : *
90 : * Initialize FD_CNG
91 : *-------------------------------------------------------------------*/
92 :
93 1930 : void initFdCngEnc(
94 : HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: Contains the variables related to the FD-based CNG process */
95 : const int32_t input_Fs, /* i : input signal sampling frequency in Hz */
96 : const float scale /* i : scaling factor */
97 : )
98 : {
99 : int16_t j;
100 1930 : HANDLE_FD_CNG_COM hsCom = hFdCngEnc->hFdCngCom;
101 :
102 : /* Initialize common */
103 1930 : initFdCngCom( hsCom, scale );
104 :
105 : /* Configure the Noise Estimator */
106 1930 : hsCom->numSlots = 16;
107 1930 : hsCom->numCoreBands = 16;
108 1930 : hsCom->regularStopBand = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH );
109 1930 : if ( hsCom->regularStopBand > 40 )
110 : {
111 922 : hsCom->regularStopBand = 40;
112 : }
113 :
114 1930 : hsCom->startBand = 2;
115 1930 : if ( hsCom->regularStopBand == 10 )
116 : {
117 16 : hsCom->stopFFTbin = 160;
118 16 : hsCom->stopBand = 160;
119 16 : hsCom->nFFTpart = 17;
120 : }
121 : else
122 : {
123 1914 : hsCom->stopFFTbin = 256;
124 1914 : hsCom->stopBand = hsCom->regularStopBand - hsCom->numCoreBands + hsCom->stopFFTbin;
125 1914 : hsCom->nFFTpart = 20;
126 : }
127 :
128 1930 : initPartitions( sidparts_encoder_noise_est, SIZE_SIDPARTS_ENC_NOISE_EST, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_inv, 0 );
129 :
130 1930 : hsCom->nCLDFBpart = hsCom->npart - hsCom->nFFTpart;
131 8155 : for ( j = 0; j < hsCom->nCLDFBpart; j++ )
132 : {
133 6225 : hsCom->CLDFBpart[j] = hsCom->part[j + hsCom->nFFTpart] - ( 256 - hsCom->startBand );
134 6225 : hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[j + hsCom->nFFTpart];
135 : }
136 :
137 : /* Initialize the Noise Estimator */
138 1930 : set_f( hFdCngEnc->msPeriodog, 0.0f, NPART );
139 1930 : set_f( hFdCngEnc->msAlpha, 0.0f, NPART );
140 1930 : set_f( hFdCngEnc->msBminWin, 0.0f, NPART );
141 1930 : set_f( hFdCngEnc->msBminSubWin, 0.0f, NPART );
142 1930 : set_f( hFdCngEnc->msPsd, 0.0f, NPART );
143 1930 : set_f( hFdCngEnc->msNoiseFloor, 0.0f, NPART );
144 1930 : set_f( hFdCngEnc->msNoiseEst, 0.0f, NPART );
145 1930 : set_f( hFdCngEnc->energy_ho, 0.0f, NPART );
146 1930 : set_f( hFdCngEnc->msNoiseEst_old, 0.0f, NPART );
147 1930 : set_f( hFdCngEnc->msMinBuf, FLT_MAX, MSNUMSUBFR * NPART );
148 1930 : set_f( hFdCngEnc->msCurrentMin, FLT_MAX, NPART );
149 1930 : set_f( hFdCngEnc->msCurrentMinOut, FLT_MAX, NPART );
150 1930 : set_f( hFdCngEnc->msCurrentMinSubWindow, FLT_MAX, NPART );
151 1930 : set_s( hFdCngEnc->msLocalMinFlag, 0, NPART );
152 1930 : set_s( hFdCngEnc->msNewMinFlag, 0, NPART );
153 1930 : set_f( hFdCngEnc->msPsdFirstMoment, 0.0f, NPART );
154 1930 : set_f( hFdCngEnc->msPsdSecondMoment, 0.0f, NPART );
155 1930 : hFdCngEnc->msPeriodogBufPtr = 0;
156 1930 : set_f( hFdCngEnc->msPeriodogBuf, 0.0f, MSBUFLEN * NPART );
157 1930 : set_f( hFdCngEnc->msLogPeriodog, 0.0f, NPART );
158 1930 : set_f( hFdCngEnc->msLogNoiseEst, 0.0f, NPART );
159 :
160 11580 : for ( int16_t i = 0; i < MDCT_ST_DTX_NUM_COHERENCE_BANDS; i++ )
161 : {
162 9650 : set_f( hFdCngEnc->mem_coherence[i], EPSILON, 4 );
163 : }
164 :
165 1930 : return;
166 : }
167 :
168 : /*-------------------------------------------------------------------*
169 : * configureFdCngEnc()
170 : *
171 : * Configure FD_CNG
172 : *-------------------------------------------------------------------*/
173 :
174 68134 : void configureFdCngEnc(
175 : HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: Contains the variables related to the FD-based CNG process */
176 : const int16_t bwidth,
177 : const int32_t total_brate )
178 : {
179 68134 : HANDLE_FD_CNG_COM hsCom = hFdCngEnc->hFdCngCom;
180 : float psizeDec[NPART];
181 : float psize_invDec[NPART];
182 :
183 68134 : hsCom->CngBandwidth = bwidth;
184 68134 : if ( hsCom->CngBandwidth == FB )
185 : {
186 52914 : hsCom->CngBandwidth = SWB;
187 : }
188 68134 : hsCom->CngBitrate = total_brate;
189 :
190 : /* NB configuration */
191 68134 : if ( bwidth == NB )
192 : {
193 27 : hsCom->FdCngSetup = FdCngSetup_nb;
194 : }
195 :
196 : /* WB configuration */
197 68107 : else if ( bwidth == WB )
198 : {
199 : /* FFT 6.4kHz, no CLDFB */
200 3698 : if ( total_brate <= ACELP_8k00 )
201 : {
202 49 : hsCom->FdCngSetup = FdCngSetup_wb1;
203 : }
204 : /* FFT 6.4kHz, CLDFB 8.0kHz */
205 3649 : else if ( total_brate <= ACELP_13k20 )
206 : {
207 1523 : hsCom->FdCngSetup = FdCngSetup_wb2;
208 : }
209 : /* FFT 8.0kHz, no CLDFB */
210 : else
211 : {
212 2126 : hsCom->FdCngSetup = FdCngSetup_wb3;
213 : }
214 : }
215 :
216 : /* SWB/FB configuration */
217 : else
218 : {
219 : /* FFT 6.4kHz, CLDFB 14kHz */
220 64409 : if ( total_brate <= ACELP_13k20 )
221 : {
222 35460 : hsCom->FdCngSetup = FdCngSetup_swb1;
223 : }
224 : /* FFT 8.0kHz, CLDFB 16kHz */
225 : else
226 : {
227 28949 : hsCom->FdCngSetup = FdCngSetup_swb2;
228 : }
229 : }
230 68134 : hsCom->fftlen = hsCom->FdCngSetup.fftlen;
231 68134 : hFdCngEnc->stopFFTbinDec = hsCom->FdCngSetup.stopFFTbin;
232 :
233 : /* Configure the SID quantizer and the Confort Noise Generator */
234 :
235 68134 : hFdCngEnc->startBandDec = hsCom->startBand;
236 68134 : hFdCngEnc->stopBandDec = hsCom->FdCngSetup.sidPartitions[hsCom->FdCngSetup.numPartitions - 1] + 1;
237 68134 : initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hFdCngEnc->startBandDec, hFdCngEnc->stopBandDec, hFdCngEnc->partDec, &hFdCngEnc->npartDec, hFdCngEnc->midbandDec, psizeDec, psize_invDec, 0 );
238 :
239 68134 : if ( hFdCngEnc->stopFFTbinDec == 160 )
240 : {
241 27 : hFdCngEnc->nFFTpartDec = 17;
242 : }
243 68107 : else if ( hFdCngEnc->stopFFTbinDec == 256 )
244 : {
245 37032 : hFdCngEnc->nFFTpartDec = 20;
246 : }
247 : else
248 : {
249 31075 : hFdCngEnc->nFFTpartDec = 21;
250 : }
251 :
252 68134 : switch ( hsCom->fftlen )
253 : {
254 37059 : case 512:
255 37059 : hsCom->fftSineTab = NULL;
256 37059 : hsCom->olapWinAna = olapWinAna512;
257 37059 : hsCom->olapWinSyn = olapWinSyn256;
258 37059 : break;
259 31075 : case 640:
260 31075 : hsCom->fftSineTab = fftSineTab640;
261 31075 : hsCom->olapWinAna = olapWinAna640;
262 31075 : hsCom->olapWinSyn = olapWinSyn320;
263 31075 : break;
264 0 : default:
265 0 : assert( !"Unsupported FFT length for FD-based CNG" );
266 : break;
267 : }
268 68134 : hsCom->frameSize = hsCom->fftlen >> 1;
269 :
270 68134 : return;
271 : }
272 :
273 :
274 : /*-------------------------------------------------------------------*
275 : * deleteFdCngEnc()
276 : *
277 : * Delete the instance of type FD_CNG
278 : *-------------------------------------------------------------------*/
279 :
280 33915 : void deleteFdCngEnc(
281 : HANDLE_FD_CNG_ENC *hFdCngEnc /* i/o: FD_CNG structure */
282 : )
283 : {
284 :
285 33915 : HANDLE_FD_CNG_ENC hsEnc = *hFdCngEnc;
286 :
287 33915 : if ( hsEnc != NULL )
288 : {
289 1930 : deleteFdCngCom( &( hsEnc->hFdCngCom ) );
290 1930 : free( hsEnc );
291 1930 : *hFdCngEnc = NULL;
292 : }
293 :
294 33915 : return;
295 : }
296 :
297 : /*-------------------------------------------------------------------*
298 : * resetFdCngEnc()
299 : *
300 : * Reset the instance of type FD_CNG
301 : *-------------------------------------------------------------------*/
302 :
303 262945 : void resetFdCngEnc(
304 : Encoder_State *st /* i/o: encoder state structure */
305 : )
306 : {
307 : int16_t n;
308 : float totalNoiseIncrease;
309 :
310 : /* Detect fast increase of totalNoise */
311 262945 : totalNoiseIncrease = st->hNoiseEst->totalNoise - st->last_totalNoise;
312 262945 : st->last_totalNoise = st->hNoiseEst->totalNoise;
313 262945 : if ( totalNoiseIncrease > 0 )
314 : {
315 22267 : if ( st->totalNoise_increase_len == TOTALNOISE_HIST_SIZE )
316 : {
317 19392 : for ( n = 0; n < TOTALNOISE_HIST_SIZE - 1; n++ )
318 : {
319 14544 : st->totalNoise_increase_hist[n] = st->totalNoise_increase_hist[n + 1];
320 : }
321 4848 : st->totalNoise_increase_hist[TOTALNOISE_HIST_SIZE - 1] = totalNoiseIncrease;
322 : }
323 : else
324 : {
325 17419 : st->totalNoise_increase_hist[st->totalNoise_increase_len] = totalNoiseIncrease;
326 17419 : st->totalNoise_increase_len++;
327 : }
328 : }
329 : else
330 : {
331 240678 : st->totalNoise_increase_len = 0;
332 : }
333 :
334 262945 : totalNoiseIncrease = 0.f;
335 309618 : for ( n = 0; n < st->totalNoise_increase_len; n++ )
336 : {
337 46673 : totalNoiseIncrease += st->totalNoise_increase_hist[n];
338 : }
339 :
340 262945 : if (
341 2156 : ( totalNoiseIncrease > 5 && st->totalNoise_increase_len == TOTALNOISE_HIST_SIZE && st->ini_frame > 150 ) ||
342 262928 : ( st->input_bwidth > st->last_input_bwidth ) ||
343 262479 : ( st->last_core == AMR_WB_CORE ) )
344 : {
345 470 : st->fd_cng_reset_flag = 1;
346 470 : st->hFdCngEnc->hFdCngCom->msFrCnt_init_counter = 0;
347 470 : st->hFdCngEnc->hFdCngCom->init_old = FLT_MAX;
348 : }
349 262475 : else if ( st->fd_cng_reset_flag > 0 && st->fd_cng_reset_flag < 10 )
350 : {
351 4187 : st->fd_cng_reset_flag++;
352 : }
353 : else
354 : {
355 258288 : st->fd_cng_reset_flag = 0;
356 : }
357 :
358 262945 : return;
359 : }
360 :
361 :
362 : /*-------------------------------------------------------------------*
363 : * perform_noise_estimation_enc()
364 : *
365 : * Perform noise estimation
366 : *-------------------------------------------------------------------*/
367 :
368 227077 : void perform_noise_estimation_enc(
369 : float *band_energies, /* i : energy in critical bands without minimum noise floor E_MIN*/
370 : float *enerBuffer, /* i : energy buffer */
371 : HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: CNG structure containing all buffers and variables */
372 : const int32_t input_Fs, /* i : input sampling rate */
373 : CPE_ENC_HANDLE hCPE /* i : CPE encoder structure */
374 : )
375 : {
376 : int16_t i, j;
377 227077 : int16_t numCoreBands = hFdCngEnc->hFdCngCom->numCoreBands;
378 227077 : int16_t regularStopBand = hFdCngEnc->hFdCngCom->regularStopBand;
379 227077 : int16_t numSlots = hFdCngEnc->hFdCngCom->numSlots;
380 227077 : float numSlots_inv = 1.f / (float) numSlots; /*enough if done only once*/
381 227077 : float *periodog = hFdCngEnc->hFdCngCom->periodog;
382 227077 : float *ptr_per = periodog;
383 227077 : int16_t npart = hFdCngEnc->hFdCngCom->npart;
384 227077 : int16_t nFFTpart = hFdCngEnc->hFdCngCom->nFFTpart;
385 227077 : float *psize = hFdCngEnc->hFdCngCom->psize;
386 227077 : float *msPeriodog = hFdCngEnc->msPeriodog;
387 227077 : float *msNoiseEst = hFdCngEnc->msNoiseEst;
388 :
389 227077 : float *msLogPeriodog = hFdCngEnc->msLogPeriodog;
390 227077 : float *msLogNoiseEst = hFdCngEnc->msLogNoiseEst;
391 :
392 : float band_res_dft, chan_width_f;
393 : float chan_width_bins;
394 : float scaleEB;
395 :
396 227077 : if ( hCPE != NULL && hCPE->hStereoDft != NULL )
397 : {
398 34018 : band_res_dft = ( (float) input_Fs ) / hCPE->hStereoDft->NFFT;
399 34018 : chan_width_f = 24000.f / CLDFB_NO_CHANNELS_MAX;
400 34018 : chan_width_bins = chan_width_f / band_res_dft;
401 :
402 : /* Scaling of Energy buffer to get energy per sample, same scaling as for band_energies, 3 is to compensate for the 1/3 scaling in calculate_energy_buffer */
403 34018 : scaleEB = 3 * 4.0f / ( hCPE->hStereoDft->NFFT * hCPE->hStereoDft->NFFT );
404 :
405 : /* Scale with number of bins in one band */
406 34018 : scaleEB = scaleEB / chan_width_bins;
407 : }
408 : else
409 : {
410 193059 : scaleEB = numSlots_inv * hFdCngEnc->hFdCngCom->scalingFactor;
411 : }
412 :
413 : /* preemphasis compensation and grouping of per bin energies into msPeriodog */
414 4766217 : for ( i = 0; i < nFFTpart; i++ )
415 : {
416 4539140 : msPeriodog[i] = 0.5f * ( band_energies[i] + band_energies[i + NB_BANDS] );
417 4539140 : msPeriodog[i] *= preemphCompensation[i];
418 : }
419 :
420 : /* Adjust to the desired time resolution by averaging the periodograms over the time slots */
421 4905325 : for ( j = numCoreBands; j < regularStopBand; j++ )
422 : {
423 4678248 : ( *ptr_per ) = enerBuffer[j] * scaleEB;
424 4678248 : ptr_per++;
425 : }
426 :
427 : /* Adjust filterbank to the desired frequency resolution by averaging over spectral partitions for SID transmission */
428 227077 : if ( numCoreBands < regularStopBand )
429 : {
430 226277 : bandcombinepow( periodog, regularStopBand - numCoreBands, hFdCngEnc->hFdCngCom->CLDFBpart, hFdCngEnc->hFdCngCom->nCLDFBpart, hFdCngEnc->hFdCngCom->CLDFBpsize_inv, &msPeriodog[nFFTpart] );
431 : }
432 :
433 : /* Compress MS inputs */
434 227077 : compress_range( msPeriodog, msLogPeriodog, npart );
435 :
436 : /* Call the minimum statistics routine for noise estimation */
437 320771 : minimum_statistics( npart, nFFTpart, psize, msLogPeriodog, hFdCngEnc->msNoiseFloor, msLogNoiseEst, hFdCngEnc->msAlpha, hFdCngEnc->msPsd, hFdCngEnc->msPsdFirstMoment, hFdCngEnc->msPsdSecondMoment, hFdCngEnc->msMinBuf, hFdCngEnc->msBminWin, hFdCngEnc->msBminSubWin, hFdCngEnc->msCurrentMin, hFdCngEnc->msCurrentMinOut, hFdCngEnc->msCurrentMinSubWindow, hFdCngEnc->msLocalMinFlag, hFdCngEnc->msNewMinFlag, hFdCngEnc->msPeriodogBuf, &( hFdCngEnc->msPeriodogBufPtr ), hFdCngEnc->hFdCngCom,
438 93694 : ENC, ( hCPE == NULL ) ? 0 : hCPE->element_mode );
439 :
440 : /* Expand MS outputs */
441 227077 : expand_range( msLogNoiseEst, msNoiseEst, npart );
442 :
443 227077 : return;
444 : }
445 :
446 :
447 : /*-------------------------------------------------------------------*
448 : * AdjustFirstSID()
449 : *
450 : * Adjust the noise estimator at the beginning of each CNG phase (encoder-side)
451 : *-------------------------------------------------------------------*/
452 :
453 216347 : void AdjustFirstSID(
454 : Encoder_State *st /* i/o: encoder state structure */
455 : )
456 : {
457 : float lambda;
458 : int16_t i;
459 216347 : int16_t npart = st->hFdCngEnc->hFdCngCom->npart;
460 216347 : float *msPeriodog = st->hFdCngEnc->msPeriodog;
461 216347 : float *energy_ho = st->hFdCngEnc->energy_ho;
462 216347 : float *msNoiseEst = st->hFdCngEnc->msNoiseEst;
463 216347 : float *msNoiseEst_old = st->hFdCngEnc->msNoiseEst_old;
464 216347 : int16_t *active_frame_counter = &( st->hFdCngEnc->hFdCngCom->active_frame_counter );
465 :
466 216347 : if ( st->hDtxEnc->cnt_SID == 1 && st->last_core_brate > SID_2k40 )
467 : {
468 : /* Detect the hangover period and the first SID frame at the beginning of each CNG phase */
469 :
470 : /* Average input energy over hangover period */
471 2956 : mvr2r( msPeriodog, energy_ho, npart ); /*First hangover frame*/
472 : /* Set first SID to current input level but add some smoothing */
473 2956 : lambda = (float) pow( 0.96f, (float) ( *active_frame_counter + 1 ) );
474 2956 : v_multc( msNoiseEst_old, lambda, msNoiseEst_old, npart );
475 2956 : v_multc( energy_ho, 1 - lambda, energy_ho, npart );
476 :
477 2956 : v_add( msNoiseEst_old, energy_ho, energy_ho, npart );
478 73312 : for ( i = 0; i < npart; i++ )
479 : {
480 70356 : if ( msNoiseEst[i] > energy_ho[i] )
481 : {
482 42318 : msNoiseEst[i] = energy_ho[i];
483 : }
484 : }
485 2956 : *active_frame_counter = 0;
486 : }
487 :
488 216347 : if ( st->core_brate != SID_2k40 && st->core_brate != FRAME_NO_DATA )
489 : {
490 180840 : ( *active_frame_counter )++; /* Count the number of active frames in a row */
491 : }
492 : else
493 : {
494 35507 : mvr2r( msNoiseEst, msNoiseEst_old, npart ); /* Store the noise estimate obtained in the CNG phases */
495 : }
496 :
497 216347 : return;
498 : }
499 :
500 : /*-------------------------------------------------------------------*
501 : * FdCng_encodeSID()
502 : *
503 : * Generate a bitstream out of the partition levels
504 : *-------------------------------------------------------------------*/
505 :
506 2281 : void FdCng_encodeSID(
507 : Encoder_State *st /* i/o: encoder state structure */
508 : )
509 : {
510 : int16_t N;
511 2281 : HANDLE_FD_CNG_ENC hFdCngEnc = st->hFdCngEnc;
512 2281 : HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
513 2281 : BSTR_ENC_HANDLE hBstr = st->hBstr;
514 2281 : float *E = hFdCngEnc->msNoiseEst;
515 : float gain;
516 : int16_t i, index;
517 : float v[32], e;
518 : int16_t indices[32];
519 : float w[32];
520 2281 : float preemph_fac = st->preemph_fac;
521 :
522 : float *invTrfMatrix;
523 : float tmpRAM[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
524 : float dct_target[FDCNG_VQ_DCT_MAXTRUNC];
525 : float tot_sig_ext[FDCNG_VQ_MAX_LEN];
526 2281 : const float gain_q_offset = ( st->element_mode == EVS_MONO ) ? GAIN_Q_OFFSET_EVS : GAIN_Q_OFFSET_IVAS;
527 :
528 : /* Init */
529 2281 : N = hFdCngEnc->npartDec;
530 :
531 2281 : invTrfMatrix = (float *) tmpRAM; /* dynamically filled */
532 2281 : set_zero( v, FDCNG_VQ_MAX_LEN );
533 :
534 : /* Convert to LOG */
535 2281 : e = 0.f;
536 55531 : for ( i = 0; i < N; i++ )
537 : {
538 53250 : v[i] = 10.f * (float) log10( E[i] + 1e-4f );
539 53250 : e += v[i];
540 : }
541 :
542 : /* Normalize MSVQ input */
543 2281 : gain = 0.f;
544 31934 : for ( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ )
545 : {
546 29653 : gain += v[i];
547 : }
548 :
549 2281 : gain /= (float) ( N_GAIN_MAX - N_GAIN_MIN );
550 :
551 55531 : for ( i = 0; i < N; i++ )
552 : {
553 53250 : v[i] -= gain;
554 : }
555 :
556 : /* MSVQ encoder */
557 2281 : set_f( w, 1.0f, N );
558 :
559 2281 : if ( st->element_mode != EVS_MONO )
560 : {
561 : /* DCT domain compressed/truncated indices used for first stage */
562 : /* quantization with stage1 stored in DCT24 domain, stages 2 through 6 directly dearched
563 : in FDCNG band domain
564 : */
565 2281 : if ( N == FDCNG_VQ_MAX_LEN_WB )
566 : {
567 498 : create_IDCT_N_Matrix( invTrfMatrix, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) );
568 : /* truncated DCT21 analysis */
569 498 : dctT2_N_apply_matrix( (const float *) v, dct_target, FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX );
570 : /* truncated IDCT21 extension to 24 bands */
571 498 : extend_dctN_input( v, dct_target, N, tot_sig_ext, FDCNG_VQ_MAX_LEN, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 );
572 :
573 498 : mvr2r( tot_sig_ext, v, FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 */
574 : }
575 2281 : create_IDCT_N_Matrix( invTrfMatrix, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) );
576 2281 : msvq_enc( cdk_37bits_ivas, NULL, NULL, v, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w, N, FD_CNG_maxN_37bits, 1, invTrfMatrix, indices );
577 2281 : msvq_dec( cdk_37bits_ivas, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix, v, NULL );
578 : }
579 : else
580 : { /* EVS_MONO tables */
581 0 : msvq_enc( cdk_37bits, NULL, NULL, v, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w, N, FD_CNG_maxN_37bits, 0, NULL, indices );
582 0 : msvq_dec( cdk_37bits, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v, NULL );
583 : }
584 :
585 :
586 : /* Compute gain */
587 2281 : gain = 0.f;
588 55531 : for ( i = 0; i < N; i++ )
589 : {
590 53250 : gain += v[i];
591 : }
592 :
593 2281 : gain = ( e - gain ) / (float) N;
594 :
595 : /* Apply bitrate-dependant scale */
596 2281 : if ( st->element_mode > EVS_MONO )
597 : {
598 2281 : apply_scale( &gain, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
599 : }
600 : else
601 : {
602 0 : apply_scale( &gain, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO );
603 : }
604 :
605 : /* Quantize gain */
606 2281 : index = (int16_t) floor( gain * 1.5f + gain_q_offset + 0.5f );
607 :
608 2281 : if ( index < 0 )
609 : {
610 300 : index = 0;
611 : }
612 :
613 2281 : if ( index > 127 )
614 : {
615 0 : index = 127;
616 : }
617 :
618 2281 : gain = ( (float) index - gain_q_offset ) / 1.5f;
619 :
620 : /* Apply gain and undo log */
621 55531 : for ( i = 0; i < N; i++ )
622 : {
623 :
624 53250 : hFdCngCom->sidNoiseEst[i] = (float) pow( 10.f, ( v[i] + gain ) / 10.f );
625 : }
626 :
627 : /* NB last band energy compensation */
628 2281 : if ( hFdCngCom->CngBandwidth == NB )
629 : {
630 0 : hFdCngCom->sidNoiseEst[N - 1] *= NB_LAST_BAND_SCALE;
631 : }
632 :
633 2281 : if ( hFdCngCom->CngBandwidth == SWB && hFdCngCom->CngBitrate <= ACELP_13k20 )
634 : {
635 973 : hFdCngCom->sidNoiseEst[N - 1] *= SWB_13k2_LAST_BAND_SCALE;
636 : }
637 :
638 : /* Write bitstream */
639 2281 : if ( st->codec_mode == MODE2 )
640 : {
641 0 : for ( i = 0; i < FD_CNG_stages_37bits; i++ )
642 : {
643 0 : push_next_indice( hBstr, indices[i], bits_37bits[i] );
644 : }
645 :
646 0 : push_next_indice( hBstr, index, 7 );
647 : }
648 : else
649 : {
650 2281 : push_indice( hBstr, IND_SID_TYPE, 1, 1 );
651 2281 : push_indice( hBstr, IND_BWIDTH, st->bwidth, 2 );
652 2281 : push_indice( hBstr, IND_ACELP_16KHZ, st->L_frame == L_FRAME16k ? 1 : 0, 1 );
653 :
654 15967 : for ( i = 0; i < FD_CNG_stages_37bits; i++ )
655 : {
656 13686 : push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] );
657 : }
658 :
659 2281 : push_indice( hBstr, IND_ENERGY, index, 7 );
660 : }
661 :
662 : /* Interpolate the bin/band-wise levels from the partition levels */
663 2281 : scalebands( hFdCngCom->sidNoiseEst, hFdCngEnc->partDec, hFdCngEnc->npartDec, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, hFdCngEnc->stopBandDec - hFdCngEnc->startBandDec, hFdCngCom->cngNoiseLevel, 1 );
664 :
665 2281 : lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, preemph_fac );
666 :
667 2281 : return;
668 : }
669 :
670 :
671 : /*-------------------------------------------------------------------*
672 : * generate_comfort_noise_enc()
673 : *
674 : *
675 : *-------------------------------------------------------------------*/
676 :
677 13847 : void generate_comfort_noise_enc(
678 : Encoder_State *st /* i/o: encoder state structure */
679 : )
680 : {
681 : int16_t i;
682 : float *ptr_r;
683 : float *ptr_i;
684 13847 : HANDLE_FD_CNG_ENC hFdCngEnc = st->hFdCngEnc;
685 13847 : HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
686 13847 : float *cngNoiseLevel = hFdCngCom->cngNoiseLevel;
687 13847 : float *ptr_level = cngNoiseLevel;
688 13847 : int16_t *seed = &( hFdCngCom->seed );
689 13847 : float scale = 1.f;
690 13847 : float *fftBuffer = hFdCngCom->fftBuffer;
691 13847 : float *timeDomainOutput = hFdCngCom->timeDomainBuffer;
692 13847 : float preemph_fac = st->preemph_fac;
693 13847 : int16_t tcx_transition = 0;
694 : float enr;
695 :
696 : /* Generate Gaussian random noise in real and imaginary parts of the FFT bins
697 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin */
698 13847 : if ( hFdCngEnc->startBandDec == 0 )
699 : {
700 0 : rand_gauss( &fftBuffer[0], seed );
701 0 : fftBuffer[0] *= (float) sqrt( scale * *ptr_level ); /* DC component in FFT */
702 0 : ptr_level++;
703 0 : ptr_r = fftBuffer + 2;
704 : }
705 : else
706 : {
707 13847 : fftBuffer[0] = 0.f;
708 13847 : set_f( fftBuffer + 2, 0.0f, 2 * ( hFdCngEnc->startBandDec - 1 ) );
709 13847 : ptr_r = fftBuffer + 2 * hFdCngEnc->startBandDec;
710 : }
711 :
712 13847 : ptr_i = ptr_r + 1;
713 3930153 : for ( ; ptr_level < cngNoiseLevel + hFdCngEnc->stopFFTbinDec - hFdCngEnc->startBandDec; ptr_level++ )
714 : {
715 : /* Real part in FFT bins */
716 3916306 : rand_gauss( ptr_r, seed );
717 3916306 : ( *ptr_r ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
718 3916306 : ptr_r += 2;
719 : /* Imaginary part in FFT bins */
720 3916306 : rand_gauss( ptr_i, seed );
721 3916306 : ( *ptr_i ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
722 3916306 : ptr_i += 2;
723 : }
724 :
725 : /* Remaining FFT bins are set to zero */
726 13847 : set_f( fftBuffer + 2 * hFdCngEnc->stopFFTbinDec, 0.0f, hFdCngCom->fftlen - 2 * hFdCngEnc->stopFFTbinDec );
727 :
728 : /* Nyquist frequency is discarded */
729 13847 : fftBuffer[1] = 0.f;
730 :
731 : /* If previous frame is active, reset the overlap-add buffer */
732 13847 : if ( st->last_core_brate > SID_2k40 )
733 : {
734 905 : set_f( hFdCngCom->olapBufferSynth, 0.0f, hFdCngCom->fftlen );
735 :
736 905 : if ( ( st->last_core > ACELP_CORE && st->codec_mode == MODE2 ) || st->codec_mode == MODE1 )
737 : {
738 905 : tcx_transition = 1;
739 : }
740 : }
741 :
742 : /* Perform STFT synthesis */
743 13847 : SynthesisSTFT( fftBuffer, timeDomainOutput, hFdCngCom->olapBufferSynth, hFdCngCom->olapWinSyn, tcx_transition, hFdCngCom, -1, -1 );
744 :
745 13847 : if ( st->hTdCngEnc != NULL )
746 : {
747 : /* update CNG excitation energy for LP_CNG */
748 : /* calculate the residual signal energy */
749 11217 : enr = cng_energy( st->element_mode, st->bwidth, st->hDtxEnc->CNG_mode, st->hTdCngEnc->CNG_att, hFdCngCom->exc_cng, hFdCngCom->frameSize );
750 :
751 11217 : st->hTdCngEnc->lp_ener = (float) ( 0.8f * st->hTdCngEnc->lp_ener + 0.2f * pow( 2.0f, enr ) );
752 : }
753 :
754 : /* Overlap-add when previous frame is active */
755 13847 : if ( st->last_core_brate > SID_2k40 && st->codec_mode == MODE2 )
756 : {
757 0 : float noise[2048], old_exc_ener = 0.f, gain = 0.f, tmp;
758 0 : int16_t N = hFdCngCom->frameSize;
759 0 : int16_t seed_loc = hFdCngCom->seed;
760 : float *old_exc, old_Aq[M + 1], *old_syn_pe, old_syn;
761 :
762 0 : if ( st->last_core > ACELP_CORE )
763 : {
764 0 : tcx_windowing_synthesis_current_frame( timeDomainOutput, st->hTcxCfg->tcx_mdct_window, /*Keep sine windows for limiting Time modulation*/
765 0 : st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, 0, st->hTcxCfg->tcx_last_overlap_mode == ALDO_WINDOW ? FULL_OVERLAP : st->hTcxCfg->tcx_last_overlap_mode, NULL, NULL, NULL, NULL, NULL, N / 2, st->hTcxCfg->tcx_offset < 0 ? -st->hTcxCfg->tcx_offset : 0, 1, 0, 0 );
766 :
767 0 : if ( st->hTcxCfg->last_aldo )
768 : {
769 0 : for ( i = 0; i < hFdCngCom->frameSize; i++ )
770 : {
771 0 : timeDomainOutput[i] += st->hTcxEnc->old_out[i + NS2SA( st->sr_core, N_ZERO_MDCT_NS )];
772 : }
773 : }
774 : else
775 : {
776 0 : 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, st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->hTcxCfg->tcx_last_overlap_mode );
777 :
778 0 : for ( i = 0; i < st->hTcxCfg->tcx_mdct_window_length; i++ )
779 : {
780 0 : timeDomainOutput[i] += st->hTcxEnc->Txnq[i];
781 : }
782 : }
783 : }
784 : else
785 : {
786 0 : lsp2a_stab( st->lsp_old, old_Aq, M );
787 0 : old_exc = st->hLPDmem->old_exc + L_EXC_MEM - ( N / 2 );
788 0 : old_syn_pe = st->hLPDmem->mem_syn2;
789 0 : old_syn = st->hLPDmem->syn[M];
790 0 : for ( i = 0; i < N / 2; i++ )
791 : {
792 0 : old_exc_ener += old_exc[i] * old_exc[i];
793 : }
794 :
795 0 : old_exc_ener = (float) sqrt( old_exc_ener / (float) ( N / 2 ) );
796 :
797 0 : for ( i = 0; i < N; i++ )
798 : {
799 0 : rand_gauss( &( noise[i] ), &( seed_loc ) );
800 0 : gain += noise[i] * noise[i];
801 : }
802 :
803 0 : gain = old_exc_ener / (float) sqrt( gain / (float) N );
804 :
805 0 : for ( i = 0; i < N; i++ )
806 : {
807 0 : noise[i] *= gain;
808 : }
809 :
810 0 : syn_filt( old_Aq, M, noise, noise, N, old_syn_pe, 0 );
811 :
812 0 : tmp = old_syn;
813 :
814 0 : deemph( noise, preemph_fac, N, &tmp );
815 :
816 0 : for ( i = 0; i < N / 2; i++ )
817 : {
818 0 : timeDomainOutput[i] += noise[i] * hFdCngCom->olapWinSyn[N / 2 + i];
819 : }
820 : }
821 : }
822 :
823 13847 : return;
824 : }
825 :
826 : /*-------------------------------------------------------------------*
827 : * cng_energy()
828 : *
829 : *
830 : *-------------------------------------------------------------------*/
831 :
832 : /*! r: CNG energy */
833 12764 : float cng_energy(
834 : const int16_t element_mode, /* i : element mode */
835 : const int16_t bwidth, /* i : audio bandwidh */
836 : const int16_t CNG_mode, /* i : mode for DTX configuration */
837 : const float CNG_att, /* i : attenuation factor for CNG */
838 : const float *exc, /* i : input signal */
839 : const int16_t len /* i : vector length */
840 : )
841 : {
842 : float enr, att;
843 :
844 : /* calculate the residual signal energy */
845 12764 : enr = dotp( exc, exc, len ) / len;
846 :
847 : /* convert log2 of residual signal energy */
848 12764 : enr = (float) log10( enr + 0.1f ) / (float) log10( 2.0f );
849 :
850 : /* decrease the energy in case of WB input */
851 12764 : if ( element_mode == IVAS_CPE_DFT || element_mode == IVAS_CPE_TD )
852 : {
853 9740 : enr += CNG_att * FAC_LOG2 / 10.0f;
854 : }
855 3024 : else if ( bwidth != NB )
856 : {
857 3024 : if ( bwidth == WB )
858 : {
859 1743 : if ( CNG_mode >= 0 )
860 : {
861 : /* Bitrate adapted attenuation */
862 0 : att = ENR_ATT[CNG_mode];
863 : }
864 : else
865 : {
866 : /* Use least attenuation for higher bitrates */
867 1743 : att = ENR_ATT[4];
868 : }
869 : }
870 : else
871 : {
872 1281 : att = 1.5f;
873 : }
874 3024 : enr -= att;
875 : }
876 :
877 12764 : return ( enr );
878 : }
879 :
880 :
881 : /*-------------------------------------------------------------------*
882 : * stereoFdCngCoherence()
883 : *
884 : * compute coherence of channels for use in FD-CNG
885 : *-------------------------------------------------------------------*/
886 :
887 28938 : void stereoFdCngCoherence(
888 : Encoder_State **sts, /* i/o: core encoder structures */
889 : const int16_t last_element_mode, /* i : last element mode */
890 : float fft_buff[CPE_CHANNELS][2 * L_FFT] /* i : fft buffers for L and R channels */
891 : )
892 : {
893 : const float *pt_fftL, *pt_fftR;
894 : int16_t i_subfr, i;
895 : float cr, ci, eL, eR;
896 : float *mem;
897 :
898 28938 : if ( last_element_mode != IVAS_CPE_MDCT )
899 : {
900 546 : for ( i = 0; i < MDCT_ST_DTX_NUM_COHERENCE_BANDS; i++ )
901 : {
902 455 : set_f( sts[0]->hFdCngEnc->mem_coherence[i], EPSILON, 4 );
903 : }
904 : }
905 :
906 28938 : if ( sts[0]->core_brate == -1 || sts[1]->core_brate == -1 )
907 : {
908 : /* case: at least one channel has triggered VAD -> ACTIVE FRAME */
909 24503 : if ( sts[0]->core_brate == -1 )
910 : {
911 23948 : sts[1]->total_brate = sts[0]->total_brate;
912 23948 : sts[1]->active_cnt = sts[0]->active_cnt;
913 23948 : if ( sts[1]->active_cnt >= CNG_TYPE_HO )
914 : {
915 22653 : sts[1]->last_total_brate_cng = -1;
916 : }
917 : }
918 24503 : if ( sts[1]->core_brate == -1 )
919 : {
920 23930 : sts[0]->total_brate = sts[1]->total_brate;
921 23930 : sts[0]->active_cnt = sts[1]->active_cnt;
922 23930 : if ( sts[0]->active_cnt >= CNG_TYPE_HO )
923 : {
924 22728 : sts[0]->last_total_brate_cng = -1;
925 : }
926 : }
927 24503 : sts[0]->core_brate = -1;
928 24503 : sts[1]->core_brate = -1;
929 24503 : sts[0]->hDtxEnc->cnt_SID = 0;
930 24503 : sts[1]->hDtxEnc->cnt_SID = 0;
931 : }
932 4435 : else if ( sts[0]->core_brate <= SID_2k40 && sts[1]->core_brate <= SID_2k40 )
933 : {
934 : /* case: no VAD for both channels -> INACTIVE FRAME */
935 4435 : reset_indices_enc( sts[0]->hBstr, sts[0]->hBstr->nb_ind_tot );
936 :
937 4435 : reset_indices_enc( sts[1]->hBstr, sts[1]->hBstr->nb_ind_tot );
938 :
939 : /* synchronize SID sending for variable SID rate */
940 4435 : if ( sts[0]->core_brate != sts[1]->core_brate )
941 : {
942 0 : sts[0]->core_brate = SID_2k40;
943 0 : sts[1]->core_brate = SID_2k40;
944 : }
945 :
946 : /* synchronize SID counters */
947 4435 : sts[0]->hDtxEnc->cnt_SID = min( sts[0]->hDtxEnc->cnt_SID, sts[1]->hDtxEnc->cnt_SID );
948 4435 : sts[1]->hDtxEnc->cnt_SID = sts[0]->hDtxEnc->cnt_SID;
949 : }
950 :
951 28938 : pt_fftL = fft_buff[0];
952 28938 : pt_fftR = fft_buff[1];
953 :
954 : /* only estimate coherence in inactive frames (or in the first 50 frames to build an initial value) */
955 28938 : if ( !( sts[0]->ini_frame <= 50 || ( sts[0]->vad_flag == 0 && sts[1]->vad_flag == 0 ) ) )
956 : {
957 14540 : return;
958 : }
959 :
960 43194 : for ( i_subfr = 0; i_subfr < 2; i_subfr++ )
961 : {
962 : int16_t band_len_cum;
963 :
964 28796 : band_len_cum = 0;
965 28796 : i = MDCT_ST_DTX_FIRST_BAND_OFFSET;
966 :
967 172776 : for ( int16_t b = 0; b < MDCT_ST_DTX_NUM_COHERENCE_BANDS; b++ )
968 : {
969 143980 : band_len_cum += mdct_stereo_dtx_coherence_bandlengths[b];
970 143980 : cr = ci = eL = eR = EPSILON;
971 143980 : mem = sts[0]->hFdCngEnc->mem_coherence[b];
972 :
973 : /* for last band, we need to make adjustments to fit with the FFT buffer layout */
974 : /* do the calculations for fftbin 0 (not anymore as it is skipped - we only calculate coherence above the 2nd bin) and L_FFT/2 outside the loop - imaginary part is always zero there, but not part of the buffer */
975 143980 : if ( b == MDCT_ST_DTX_NUM_COHERENCE_BANDS - 1 )
976 : {
977 : /* this calculates values for fft bin at L_FFT/2 - no imaginary value there, not even part of the array */
978 28796 : cr += pt_fftL[L_FFT / 2] * pt_fftR[L_FFT / 2];
979 28796 : eL += pt_fftL[L_FFT / 2] * pt_fftL[L_FFT / 2];
980 28796 : eR += pt_fftR[L_FFT / 2] * pt_fftR[L_FFT / 2];
981 :
982 : /* skip last fft bin (fs/2 Hz) bin in the loop later */
983 28796 : --band_len_cum;
984 : }
985 :
986 3685888 : for ( ; i < band_len_cum; i++ )
987 : {
988 3541908 : cr += pt_fftL[i] * pt_fftR[i] + pt_fftL[L_FFT - i] * pt_fftR[L_FFT - i];
989 3541908 : ci += -pt_fftL[i] * pt_fftR[L_FFT - i] + pt_fftR[i] * pt_fftL[L_FFT - i];
990 3541908 : eL += pt_fftL[i] * pt_fftL[i] + pt_fftL[L_FFT - i] * pt_fftL[L_FFT - i];
991 3541908 : eR += pt_fftR[i] * pt_fftR[i] + pt_fftR[L_FFT - i] * pt_fftR[L_FFT - i];
992 : }
993 :
994 143980 : mem[0] = 0.95f * mem[0] + 0.05f * cr;
995 143980 : mem[1] = 0.95f * mem[1] + 0.05f * ci;
996 143980 : mem[2] = 0.95f * mem[2] + 0.05f * eL;
997 143980 : mem[3] = 0.95f * mem[3] + 0.05f * eR;
998 :
999 : /* could be done outside the loop, as the second assignment overwrites the first, but this would mean a second loop over bands */
1000 143980 : sts[0]->hFdCngEnc->hFdCngCom->coherence[b] = sqrtf( ( mem[0] * mem[0] + mem[1] * mem[1] ) / ( mem[2] * mem[3] ) );
1001 : }
1002 :
1003 28796 : pt_fftL += L_FFT;
1004 28796 : pt_fftR += L_FFT;
1005 : }
1006 :
1007 14398 : return;
1008 : }
1009 :
1010 :
1011 : /*-------------------------------------------------------------------*
1012 : * FdCngEncodeMDCTStereoSID()
1013 : *
1014 : * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX
1015 : *-------------------------------------------------------------------*/
1016 :
1017 471 : void FdCngEncodeMDCTStereoSID(
1018 : CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure */
1019 : )
1020 : {
1021 : ENC_CORE_HANDLE sts[CPE_CHANNELS];
1022 : float *lr_in_ptr[CPE_CHANNELS];
1023 : float *ms_ptr[CPE_CHANNELS];
1024 : float *lr_out_ptr[CPE_CHANNELS];
1025 : float logNoiseEst[CPE_CHANNELS][NPART];
1026 : float E[CPE_CHANNELS];
1027 : float gain[CPE_CHANNELS];
1028 : float weights[NPART];
1029 : int16_t indices[CPE_CHANNELS][FD_CNG_stages_37bits];
1030 : int16_t gain_idx[CPE_CHANNELS];
1031 : int16_t N, stages, ch, p, coh_idx;
1032 : float side_energy;
1033 : int16_t no_side_flag;
1034 : int16_t is_inp_ms;
1035 :
1036 : float tot_sig_ext[FDCNG_VQ_MAX_LEN], dct_target[CPE_CHANNELS][FDCNG_VQ_DCT_MAXTRUNC]; /* 24 +2*18*/
1037 : float *invTrfMatrix;
1038 : float tmpRAM[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; /*24*18*/
1039 471 : invTrfMatrix = (float *) tmpRAM; /* dynamically filled */
1040 :
1041 :
1042 471 : is_inp_ms = 0;
1043 471 : if ( hCPE->hCoreCoder[0]->cng_sba_flag == 1 )
1044 : {
1045 0 : is_inp_ms = 1;
1046 : }
1047 :
1048 : /* set pointers and initialize */
1049 1413 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
1050 : {
1051 942 : sts[ch] = hCPE->hCoreCoder[ch];
1052 942 : lr_in_ptr[ch] = &sts[ch]->hFdCngEnc->msNoiseEst[0];
1053 942 : ms_ptr[ch] = &logNoiseEst[ch][0];
1054 942 : lr_out_ptr[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0];
1055 : }
1056 : #ifdef DEBUGGING
1057 : assert( sts[0]->hFdCngEnc->npartDec == sts[1]->hFdCngEnc->npartDec );
1058 : #endif
1059 471 : N = sts[0]->hFdCngEnc->npartDec;
1060 471 : set_f( weights, 1.f, NPART );
1061 :
1062 : /* apply log and save energy of original left and right channels */
1063 1413 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
1064 : {
1065 942 : E[ch] = 0.0f;
1066 22482 : for ( p = 0; p < N; p++ )
1067 : {
1068 21540 : ms_ptr[ch][p] = 10.f * log10f( lr_in_ptr[ch][p] + EPSILON );
1069 21540 : E[ch] += ms_ptr[ch][p];
1070 : }
1071 : }
1072 :
1073 : /* M/S transform on log envelopes */
1074 471 : if ( is_inp_ms == 0 )
1075 : {
1076 471 : convertToMS( N, ms_ptr[0], ms_ptr[1], 0.5f );
1077 : }
1078 :
1079 471 : side_energy = sum2_f( ms_ptr[1], N );
1080 :
1081 : /* do not transmit side shape if initial noise shapes are very similar */
1082 471 : if ( side_energy <= 0.1f )
1083 : {
1084 16 : no_side_flag = 1;
1085 : }
1086 : else
1087 : {
1088 455 : no_side_flag = 0;
1089 : }
1090 :
1091 : /* Quantize noise shapes */
1092 1413 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
1093 : {
1094 : /* Normalize MSVQ input */
1095 942 : gain[ch] = 0.f;
1096 13188 : for ( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ )
1097 : {
1098 12246 : gain[ch] += ms_ptr[ch][p];
1099 : }
1100 942 : gain[ch] /= (float) ( N_GAIN_MAX - N_GAIN_MIN );
1101 :
1102 22482 : for ( p = 0; p < N; p++ )
1103 : {
1104 21540 : ms_ptr[ch][p] -= gain[ch];
1105 : }
1106 : }
1107 : /* always split channel targetloop */
1108 :
1109 : /* extend fdcng envelope from length 21 to a 24 length fdncg domain envelope signal */
1110 : /* High quality cosine smooth basis extension used to not introduce noise in stage#1 DCT24 analysis and subsequent VQ-steps */
1111 471 : if ( N == FDCNG_VQ_MAX_LEN_WB )
1112 : {
1113 178 : create_IDCT_N_Matrix( invTrfMatrix, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); /*WB: create truncated IDCT21 matrix */
1114 :
1115 534 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
1116 : {
1117 : /* run DCT_N N==21 , truncated at 18/21 ~= 86% , i.e use a bit better better quality in extrapolation , than subsequent DCT24 analysis which is truncated at 75%*/
1118 :
1119 : /* truncated DCT 21 analysis */
1120 356 : dctT2_N_apply_matrix( (const float *) ms_ptr[ch], dct_target[ch], FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX );
1121 :
1122 : /* extrapolate extend fdcng envelope signal in the fdncg ienvelope/"time" domain using DCT21 basis vectors,
1123 : estimated DCT21 coeffs scaling extended basis vectors are used to create extrapolated length 24 input target envelope signal */
1124 : /* this DCT21 extension does not introduce DCT24 coefficient noise for the subsequent dct24 target analysis, and later in IDCT24 synthesis */
1125 :
1126 : /* truncated IDCT 21 extension synthesis */
1127 356 : extend_dctN_input( ms_ptr[ch], dct_target[ch], N, tot_sig_ext, FDCNG_VQ_MAX_LEN, invTrfMatrix /* DCT_N basis vectors */, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); /* use 18 basis vectors*/
1128 :
1129 356 : mvr2r( tot_sig_ext, ms_ptr[ch], FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ */
1130 : }
1131 : }
1132 471 : create_IDCT_N_Matrix( invTrfMatrix, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); /*always create/set up IDCT24 matrix in RAM */
1133 :
1134 : /* end split */
1135 1413 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
1136 : {
1137 : /* MSVQ */
1138 942 : if ( ch )
1139 : {
1140 471 : stages = FD_CNG_JOINT_stages_25bits;
1141 : }
1142 : else
1143 : {
1144 471 : stages = FD_CNG_stages_37bits;
1145 : }
1146 :
1147 : /* DCT24 domain compressed/truncated indices used for first stage */
1148 : /* mid channel quantization using stages 1 through 6 */
1149 : /* & side channel quantization using stages 1 through 4 */
1150 :
1151 : {
1152 942 : msvq_enc( cdk_37bits_ivas, NULL, NULL, ms_ptr[ch], levels_37bits, FD_CNG_maxC_37bits, stages, weights, N, FD_CNG_maxN_37bits, 1, invTrfMatrix, indices[ch] );
1153 942 : msvq_dec( cdk_37bits_ivas, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices[ch], 1, invTrfMatrix, ms_ptr[ch], NULL );
1154 : }
1155 : }
1156 :
1157 471 : if ( no_side_flag )
1158 : {
1159 16 : set_zero( ms_ptr[1], N );
1160 : }
1161 :
1162 : /* undo M/S */
1163 471 : if ( is_inp_ms == 0 )
1164 : {
1165 471 : convertToMS( N, ms_ptr[0], ms_ptr[1], 1.0f );
1166 : }
1167 :
1168 : /* Compute gain against original left and right channels */
1169 1413 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
1170 : {
1171 942 : gain[ch] = 0.f;
1172 22482 : for ( p = 0; p < N; p++ )
1173 : {
1174 21540 : gain[ch] += ms_ptr[ch][p];
1175 : }
1176 942 : gain[ch] = ( E[ch] - gain[ch] ) / (float) N;
1177 942 : apply_scale( &gain[ch], sts[ch]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[ch]->element_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
1178 :
1179 : /* quantize gain */
1180 942 : gain_idx[ch] = (int16_t) floor( gain[ch] * 1.5f + GAIN_Q_OFFSET_IVAS + .5f );
1181 942 : gain_idx[ch] = max( 0, min( 127, gain_idx[ch] ) );
1182 :
1183 942 : gain[ch] = ( (float) gain_idx[ch] - GAIN_Q_OFFSET_IVAS ) / 1.5f;
1184 : }
1185 :
1186 : /* restore channel noise envelopes */
1187 1413 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
1188 : {
1189 942 : HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc;
1190 942 : HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
1191 :
1192 22482 : for ( p = 0; p < N; p++ )
1193 : {
1194 21540 : lr_out_ptr[ch][p] = powf( 10.f, ( ms_ptr[ch][p] + gain[ch] ) / 10.f );
1195 : }
1196 :
1197 : /* scale bands and get scalefactors */
1198 942 : scalebands( lr_out_ptr[ch], hFdCngEnc->partDec, N, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, hFdCngEnc->stopBandDec - hFdCngEnc->startBandDec, hFdCngCom->cngNoiseLevel, 1 );
1199 :
1200 942 : lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac );
1201 :
1202 942 : sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame;
1203 : }
1204 :
1205 : /* quantize channel coherence */
1206 471 : coh_idx = (int16_t) floor( sts[0]->hFdCngEnc->hFdCngCom->coherence[0] * 15.f + 0.5f );
1207 471 : coh_idx = max( 0, min( coh_idx, 15 ) );
1208 :
1209 : /* ---- Write SID bitstream ---- */
1210 :
1211 :
1212 : /* noise shapes and channel gains */
1213 1413 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
1214 : {
1215 942 : if ( ch )
1216 : {
1217 471 : stages = FD_CNG_JOINT_stages_25bits;
1218 471 : sts[ch]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot;
1219 :
1220 : /* side info */
1221 471 : push_indice( sts[ch]->hBstr, IND_SID_TYPE, coh_idx, 4 );
1222 471 : push_indice( sts[ch]->hBstr, IND_SID_TYPE, no_side_flag, 1 );
1223 : }
1224 : else
1225 : {
1226 471 : stages = FD_CNG_stages_37bits;
1227 : /* side info */
1228 471 : push_indice( sts[ch]->hBstr, IND_SID_TYPE, 1, 1 );
1229 471 : push_indice( sts[ch]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 );
1230 471 : push_indice( sts[ch]->hBstr, IND_ACELP_16KHZ, sts[0]->L_frame == L_FRAME16k ? 1 : 0, 1 );
1231 : }
1232 :
1233 5652 : for ( int16_t i = 0; i < stages; i++ )
1234 : {
1235 4710 : push_indice( sts[ch]->hBstr, IND_LSF, indices[ch][i], bits_37bits[i] );
1236 : }
1237 942 : push_indice( sts[ch]->hBstr, IND_ENERGY, gain_idx[ch], 7 );
1238 : }
1239 :
1240 : /* write the four additional coherence values */
1241 2355 : for ( int16_t b = 1; b < MDCT_ST_DTX_NUM_COHERENCE_BANDS; b++ )
1242 : {
1243 1884 : coh_idx = (int16_t) floor( sts[0]->hFdCngEnc->hFdCngCom->coherence[b] * 15.f + 0.5f );
1244 1884 : coh_idx = max( 0, min( coh_idx, 15 ) );
1245 1884 : push_indice( sts[1]->hBstr, IND_ENERGY, coh_idx, 4 );
1246 : }
1247 :
1248 471 : return;
1249 : }
1250 :
1251 :
1252 : /*-------------------------------------------------------------------*
1253 : * FdCngEncodeDiracMDCTStereoSID()
1254 : *
1255 : * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX
1256 : * together with Dirac
1257 : *-------------------------------------------------------------------*/
1258 :
1259 165 : void FdCngEncodeDiracMDCTStereoSID(
1260 : CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure */
1261 : )
1262 : {
1263 : ENC_CORE_HANDLE sts[CPE_CHANNELS];
1264 : float *lr_in_ptr[CPE_CHANNELS];
1265 : float *ms_ptr[CPE_CHANNELS];
1266 : float *lr_out_ptr[CPE_CHANNELS];
1267 : float logNoiseEst[CPE_CHANNELS][NPART];
1268 : float E[CPE_CHANNELS];
1269 : float gain[CPE_CHANNELS];
1270 : float weights[NPART];
1271 : int16_t N[CPE_CHANNELS];
1272 : int16_t indices[CPE_CHANNELS][FD_CNG_stages_37bits];
1273 : int16_t gain_idx[CPE_CHANNELS];
1274 : int16_t ch, p;
1275 : float *invTrfMatrix;
1276 : float tmpRAM[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
1277 : float dct_target[FDCNG_VQ_DCT_MAXTRUNC];
1278 : float tot_sig_ext[FDCNG_VQ_MAX_LEN];
1279 165 : invTrfMatrix = (float *) tmpRAM; /* dynamically filled */
1280 :
1281 : /* set pointers and initialize */
1282 495 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
1283 : {
1284 330 : sts[ch] = hCPE->hCoreCoder[ch];
1285 330 : N[ch] = sts[ch]->hFdCngEnc->npartDec;
1286 330 : lr_in_ptr[ch] = &sts[ch]->hFdCngEnc->msNoiseEst[0];
1287 330 : ms_ptr[ch] = &logNoiseEst[ch][0];
1288 330 : lr_out_ptr[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0];
1289 : }
1290 165 : set_f( weights, 1.f, NPART );
1291 : #ifdef DEBUGGING
1292 : assert( N[0] == N[1] );
1293 : #endif
1294 :
1295 : /* apply log and save energy of original left and right channels */
1296 495 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
1297 : {
1298 330 : E[ch] = 0.0f;
1299 8250 : for ( p = 0; p < N[ch]; p++ )
1300 : {
1301 7920 : ms_ptr[ch][p] = 10.f * log10f( lr_in_ptr[ch][p] + EPSILON );
1302 7920 : E[ch] += ms_ptr[ch][p];
1303 : }
1304 : }
1305 :
1306 : /* M/S transform on log envelopes */
1307 165 : convertToMS( N[0], ms_ptr[0], ms_ptr[1], 0.5f );
1308 :
1309 165 : E[0] = sum_f( ms_ptr[0], N[0] );
1310 :
1311 : /* Quantize M noise shape */
1312 : /* Normalize MSVQ input */
1313 165 : gain[0] = sum_f( ms_ptr[0] + N_GAIN_MIN, N_GAIN_MAX - N_GAIN_MIN );
1314 165 : gain[0] /= (float) ( N_GAIN_MAX - N_GAIN_MIN );
1315 :
1316 4125 : for ( p = 0; p < N[0]; p++ )
1317 : {
1318 3960 : ms_ptr[0][p] -= gain[0];
1319 : }
1320 :
1321 : /* MSVQ */
1322 : /* DCT domain compressed/truncated indices used for first stage */
1323 : /* mid quantization using stages #1 through 6 */
1324 165 : if ( N[0] == FDCNG_VQ_MAX_LEN_WB )
1325 : {
1326 0 : create_IDCT_N_Matrix( invTrfMatrix, N[0], FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) );
1327 : /* truncated DCT 21 analysis */
1328 0 : dctT2_N_apply_matrix( (const float *) ms_ptr[0], dct_target, FDCNG_VQ_DCT_MAXTRUNC, N[0], invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX );
1329 : /* truncated IDCT21 extension to 24 synthesis */
1330 0 : extend_dctN_input( ms_ptr[0], dct_target, N[0], tot_sig_ext, FDCNG_VQ_MAX_LEN, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); /* use 18 basis vectors*/
1331 :
1332 0 : mvr2r( tot_sig_ext, ms_ptr[0], FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 */
1333 : }
1334 165 : create_IDCT_N_Matrix( invTrfMatrix, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) );
1335 :
1336 165 : msvq_enc( cdk_37bits_ivas, NULL, NULL, ms_ptr[0], levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, weights, N[0], FD_CNG_maxN_37bits, 1, invTrfMatrix, indices[0] );
1337 165 : msvq_dec( cdk_37bits_ivas, NULL, NULL, FD_CNG_stages_37bits, N[0], FD_CNG_maxN_37bits, indices[0], 1, invTrfMatrix, ms_ptr[0], NULL );
1338 :
1339 :
1340 : /* set S to zero */
1341 165 : set_zero( ms_ptr[1], NPART );
1342 :
1343 : /* compute M gain */
1344 165 : gain[0] = sum_f( ms_ptr[0], N[0] );
1345 165 : gain[0] = ( E[0] - gain[0] ) / (float) N[0];
1346 165 : apply_scale( &gain[0], sts[0]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[0]->hDtxEnc->last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
1347 :
1348 : /* quantize gain */
1349 165 : gain_idx[0] = (int16_t) floor( gain[0] * 1.5f + GAIN_Q_OFFSET_IVAS + .5f );
1350 165 : gain_idx[0] = max( 0, min( 127, gain_idx[0] ) );
1351 :
1352 165 : gain[0] = ( (float) gain_idx[0] - GAIN_Q_OFFSET_IVAS ) / 1.5f;
1353 165 : gain[1] = gain[0];
1354 :
1355 : /* undo M/S */
1356 165 : convertToMS( NPART, ms_ptr[0], ms_ptr[1], 1.0f );
1357 :
1358 : /* restore channel noise envelopes */
1359 495 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
1360 : {
1361 330 : HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc;
1362 330 : HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
1363 :
1364 8250 : for ( p = 0; p < N[0]; p++ )
1365 : {
1366 7920 : lr_out_ptr[ch][p] = powf( 10.f, ( ms_ptr[ch][p] + gain[ch] ) / 10.f );
1367 : }
1368 :
1369 : /* NB last band energy compensation */
1370 330 : if ( hFdCngCom->CngBandwidth == NB )
1371 : {
1372 0 : lr_out_ptr[ch][N[ch] - 1] *= NB_LAST_BAND_SCALE;
1373 : }
1374 330 : else if ( hFdCngCom->CngBandwidth == SWB && hFdCngCom->CngBitrate <= ACELP_13k20 )
1375 : {
1376 0 : lr_out_ptr[ch][N[ch] - 1] *= SWB_13k2_LAST_BAND_SCALE;
1377 : }
1378 :
1379 : /* scale bands and get scalefactors */
1380 330 : scalebands( lr_out_ptr[ch], hFdCngEnc->partDec, N[ch], hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, hFdCngEnc->stopBandDec - hFdCngEnc->startBandDec, hFdCngCom->cngNoiseLevel, 1 );
1381 :
1382 330 : lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac );
1383 :
1384 330 : sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame;
1385 : }
1386 :
1387 165 : sts[0]->hFdCngEnc->hFdCngCom->coherence[0] = 0.0f;
1388 165 : sts[1]->hFdCngEnc->hFdCngCom->coherence[0] = 0.0f;
1389 :
1390 : /* ---- Write SID bitstream ---- */
1391 :
1392 : /* side info */
1393 165 : push_indice( sts[0]->hBstr, IND_SID_TYPE, 1, 1 );
1394 165 : push_indice( sts[0]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 );
1395 165 : push_indice( sts[0]->hBstr, IND_ACELP_16KHZ, sts[0]->L_frame == L_FRAME16k ? 1 : 0, 1 );
1396 :
1397 : /* noise shapes and channel gains */
1398 1155 : for ( int16_t i = 0; i < FD_CNG_stages_37bits; i++ )
1399 : {
1400 990 : push_indice( sts[0]->hBstr, IND_LSF, indices[0][i], bits_37bits[i] );
1401 : }
1402 165 : push_indice( sts[0]->hBstr, IND_ENERGY, gain_idx[0], 7 );
1403 :
1404 165 : return;
1405 : }
|