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