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