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 : #include <stdint.h>
34 : #include "options.h"
35 : #include <math.h>
36 : #include "cnst.h"
37 : #include "rom_enc.h"
38 : #include "rom_com.h"
39 : #include "prot.h"
40 : #include "ivas_prot.h"
41 : #include "ivas_cnst.h"
42 : #include "ivas_rom_com.h"
43 : #ifdef DEBUGGING
44 : #include "debug.h"
45 : #endif
46 : #include "wmc_auto.h"
47 :
48 :
49 : /*-------------------------------------------------------------------
50 : * Local constants
51 : *-------------------------------------------------------------------*/
52 :
53 : #define COH_FADE_MAX 4
54 : #define COH_FADE_UPDATES 2
55 :
56 :
57 : /*---------------------------------------------------------------
58 : * stereo_dft_enc_sid_calc_coh()
59 : *
60 : * Encodes the coherence in SID frames
61 : * ---------------------------------------------------------------*/
62 :
63 1445 : void stereo_dft_enc_sid_calc_coh(
64 : STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo handle */
65 : float prev_cohBand[2 * ( STEREO_DFT_BAND_MAX / 2 )], /* i/o: Previous coherence */
66 : int16_t *td_active, /* i/o: TD stereo mode indicator */
67 : int16_t *first_SID, /* i/o: First SID indicator */
68 : float *cohBand /* i/o: Coherence per band */
69 : )
70 : {
71 : int16_t b, k;
72 : float coh_weight;
73 : float coh_weight_sum;
74 : float xspec_scale;
75 : /* Cluster the coherence into bands using a weighted average. The coherence is weighted with the energy spectrum of the
76 : mixdown signal. */
77 9799 : for ( b = 0; b < hStereoDft->nbands; b++ )
78 : {
79 8354 : cohBand[b] = 0;
80 8354 : coh_weight_sum = 0;
81 :
82 8354 : if ( hStereoDft->coh_fade_counter == 0 && !*first_SID )
83 : {
84 213903 : for ( k = hStereoDft->band_limits[b]; k < hStereoDft->band_limits[b + 1]; k++ )
85 : {
86 211800 : xspec_scale = sqrtf( ( prev_cohBand[b] * ( hStereoDft->Spd_L_smooth[k] * hStereoDft->Spd_R_smooth[k] ) ) / ( hStereoDft->xspec_smooth[2 * k] * hStereoDft->xspec_smooth[2 * k] + hStereoDft->xspec_smooth[2 * k + 1] * hStereoDft->xspec_smooth[2 * k + 1] + EPSILON ) );
87 211800 : hStereoDft->xspec_smooth[2 * k] *= xspec_scale;
88 211800 : hStereoDft->xspec_smooth[2 * k + 1] *= xspec_scale;
89 : }
90 :
91 2103 : cohBand[b] = prev_cohBand[b];
92 : }
93 : else
94 : {
95 616686 : for ( k = hStereoDft->band_limits[b]; k < hStereoDft->band_limits[b + 1]; k++ )
96 : {
97 610435 : coh_weight = hStereoDft->DFT[0][2 * k] * hStereoDft->DFT[0][2 * k] + hStereoDft->DFT[0][2 * k + 1] * hStereoDft->DFT[0][2 * k + 1];
98 610435 : cohBand[b] += coh_weight * ( ( hStereoDft->xspec_smooth[2 * k] * hStereoDft->xspec_smooth[2 * k] + hStereoDft->xspec_smooth[2 * k + 1] * hStereoDft->xspec_smooth[2 * k + 1] ) / ( hStereoDft->Spd_L_smooth[k] * hStereoDft->Spd_R_smooth[k] + EPSILON ) );
99 610435 : coh_weight_sum += coh_weight;
100 : }
101 6251 : if ( coh_weight_sum > 0 )
102 : {
103 6224 : cohBand[b] = cohBand[b] / coh_weight_sum;
104 : }
105 : }
106 : }
107 :
108 1445 : if ( *first_SID )
109 : {
110 27 : mvr2r( cohBand, prev_cohBand, hStereoDft->nbands );
111 27 : mvr2r( prev_cohBand, &( prev_cohBand[STEREO_DFT_BAND_MAX / 2] ), hStereoDft->nbands );
112 27 : *first_SID = 0;
113 : }
114 :
115 1445 : if ( hStereoDft->coh_fade_counter < COH_FADE_MAX && ( *td_active || hStereoDft->currentNumUpdates < COH_FADE_UPDATES ) )
116 : {
117 224 : for ( b = 0; b < hStereoDft->nbands; b++ )
118 : {
119 191 : cohBand[b] = ( cohBand[b] * hStereoDft->coh_fade_counter + prev_cohBand[b] * ( COH_FADE_MAX - hStereoDft->coh_fade_counter ) ) / COH_FADE_MAX;
120 : }
121 33 : hStereoDft->coh_fade_counter++;
122 33 : if ( hStereoDft->coh_fade_counter > 0 )
123 : {
124 33 : mvr2r( &prev_cohBand[STEREO_DFT_BAND_MAX / 2], prev_cohBand, hStereoDft->nbands );
125 : }
126 33 : mvr2r( cohBand, &prev_cohBand[STEREO_DFT_BAND_MAX / 2], hStereoDft->nbands );
127 : }
128 : else
129 : {
130 1412 : if ( hStereoDft->coh_fade_counter > 0 )
131 : {
132 1058 : mvr2r( &prev_cohBand[STEREO_DFT_BAND_MAX / 2], prev_cohBand, hStereoDft->nbands );
133 : }
134 1412 : mvr2r( cohBand, &prev_cohBand[STEREO_DFT_BAND_MAX / 2], hStereoDft->nbands );
135 1412 : hStereoDft->coh_fade_counter = COH_FADE_MAX;
136 1412 : *td_active = 0;
137 : }
138 :
139 1445 : return;
140 : }
141 :
142 :
143 : /*---------------------------------------------------------------
144 : * stereo_dft_enc_sid_coh()
145 : *
146 : * Encodes the coherence in SID frames
147 : * ---------------------------------------------------------------*/
148 :
149 1445 : void stereo_dft_enc_sid_coh(
150 : BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */
151 : float *mem_cohBand, /* i/o: Coherence memory */
152 : const int16_t nbands, /* i : number of DFT stereo bands */
153 : int16_t *nb_bits, /* i/o: number of bits written */
154 : float *cohBand /* i/o: Coherence per band */
155 : )
156 : {
157 : int16_t b, k;
158 : int16_t zeropad;
159 : int16_t nr_of_sid_stereo_bits;
160 : int16_t coh_pred_index;
161 : float min_pred_err;
162 : float pred_err;
163 : int16_t res_index;
164 : int16_t i;
165 : float tmp;
166 : const float *pptr;
167 : float pred;
168 : float cohBandq[STEREO_DFT_BAND_MAX / 2]; /* Reconstructed coherence values for intra-frame prediction */
169 : const float *alphaptr;
170 : int16_t nbbits_test;
171 : int16_t prev_nbbits_test;
172 : int16_t alpha_step;
173 : int16_t alpha_level;
174 : int16_t n;
175 :
176 1445 : nr_of_sid_stereo_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS;
177 1445 : zeropad = 0;
178 :
179 : /* Encode coherence vector. Find best fixed predictor by minimizing prediction error on input vector.
180 : The prediction is formed by a linear combination of the previous values
181 : in the vector. Hence, prediction is only done for coefficient 1 and up.
182 : If not enough bits for at least one bit for encoding prediction
183 : residual then skip the coding and write zeroes to the bitstream if needed.
184 : In this case the decoder will set alpha to 0, i.e. reuse previous coherence */
185 :
186 1445 : if ( ( nr_of_sid_stereo_bits - *nb_bits - STEREO_DFT_N_COH_ALPHA_BITS - STEREO_DFT_PRED_NBITS ) > 0 )
187 : {
188 1445 : min_pred_err = 1e6f;
189 1445 : coh_pred_index = -1;
190 1445 : pptr = dft_cng_coh_pred[0];
191 7225 : for ( k = 0; k < STEREO_DFT_N_COH_PRED; k++ )
192 : {
193 5780 : pred_err = 0;
194 33416 : for ( b = 1; b < nbands; b++ ) /* Set b=1 to skip first coefficient (same error would otherwise be added for all predictors: (cohBand[0] - 0).^2) */
195 : {
196 27636 : pred = 0;
197 108016 : for ( i = 0; i < b; i++ )
198 : {
199 80380 : pred += ( *pptr++ ) * cohBand[i];
200 : }
201 27636 : tmp = cohBand[b] - pred;
202 27636 : pred_err += tmp * tmp;
203 : }
204 5780 : if ( pred_err < min_pred_err ) /* Store best candidate */
205 : {
206 2846 : min_pred_err = pred_err;
207 2846 : coh_pred_index = k;
208 : }
209 : }
210 :
211 1445 : push_next_indice( hBstr, coh_pred_index, STEREO_DFT_PRED_NBITS ); /* Write selected predictor to bitstream */
212 1445 : ( *nb_bits ) += STEREO_DFT_PRED_NBITS;
213 :
214 : /* Pick two different alphas (one low and one high) as a function
215 : of the number of available bits. */
216 1445 : alpha_step = 0;
217 7225 : for ( i = 0; i < STEREO_DFT_N_COH_ALPHA_STEPS - 1; i++ )
218 : {
219 5780 : if ( nr_of_sid_stereo_bits - *nb_bits - STEREO_DFT_N_COH_ALPHA_BITS > dft_cng_coh_alpha_start[i] )
220 : {
221 5780 : alpha_step = i + 1;
222 : }
223 : }
224 :
225 : /* Calculate the number of encoded bits. */
226 1445 : alphaptr = dft_cng_alpha_bits[alpha_step];
227 1445 : alpha_level = 0;
228 1445 : prev_nbbits_test = 100;
229 4335 : for ( i = 0; i < STEREO_DFT_N_COH_ALPHA_LEVELS; i++ )
230 : {
231 2890 : nbbits_test = 0;
232 2890 : pptr = dft_cng_coh_pred[coh_pred_index];
233 2890 : pred = 0.4f;
234 19598 : for ( b = 0; b < nbands; b++ )
235 : {
236 56898 : for ( n = 0; n < b; n++ )
237 : {
238 40190 : pred += ( *pptr++ ) * cohBandq[n];
239 : }
240 :
241 16708 : pred = ( *alphaptr ) * pred + ( 1 - ( *alphaptr ) ) * mem_cohBand[b];
242 16708 : pred_err = cohBand[b] - pred;
243 16708 : res_index = usquant( pred_err, &pred_err, -0.4f, 0.1f, 9 );
244 16708 : res_index = dft_cng_coh_i2u[res_index];
245 16708 : nbbits_test += res_index + 1;
246 16708 : res_index = dft_cng_coh_u2i[res_index];
247 16708 : pred_err = usdequant( res_index, -0.4f, 0.1f );
248 16708 : cohBandq[b] = pred + pred_err;
249 16708 : if ( cohBandq[b] > 1 )
250 : {
251 0 : cohBandq[b] = 1;
252 : }
253 16708 : else if ( cohBandq[b] < 0 )
254 : {
255 251 : cohBandq[b] = 0;
256 : }
257 16708 : pred = 0;
258 : }
259 :
260 2890 : if ( nbbits_test < nr_of_sid_stereo_bits - *nb_bits - STEREO_DFT_N_COH_ALPHA_BITS )
261 : {
262 2871 : alpha_level = i;
263 : }
264 :
265 2890 : if ( nbbits_test < prev_nbbits_test )
266 : {
267 1535 : alpha_level = i;
268 : }
269 :
270 2890 : prev_nbbits_test = nbbits_test;
271 2890 : alphaptr++;
272 : }
273 :
274 : /* Do the actual encoding using the selected predictor and alpha */
275 1445 : push_next_indice( hBstr, alpha_level, STEREO_DFT_N_COH_ALPHA_BITS ); /* Write selected alpha index to bitstream */
276 1445 : ( *nb_bits ) += STEREO_DFT_N_COH_ALPHA_BITS;
277 1445 : alphaptr = &dft_cng_alpha_bits[alpha_step][alpha_level];
278 1445 : pptr = dft_cng_coh_pred[coh_pred_index]; /* Set pointer to selected predictor */
279 1445 : pred = 0.4f;
280 :
281 9799 : for ( b = 0; b < nbands; b++ )
282 : {
283 : /* Intra-frame prediction using quantized values */
284 28449 : for ( i = 0; i < b; i++ )
285 : {
286 20095 : pred += ( *pptr++ ) * cohBandq[i];
287 : }
288 : /* Weighted intra/inter-frame prediction */
289 8354 : pred = ( *alphaptr ) * pred + ( 1 - ( *alphaptr ) ) * mem_cohBand[b];
290 8354 : pred_err = cohBand[b] - pred;
291 8354 : res_index = usquant( pred_err, &pred_err, -0.4f, 0.1f, 9 ); /* Quantize prediction residual */
292 8354 : res_index = dft_cng_coh_i2u[res_index]; /* Convert to unary codeword - res_index+1 now equal to codeword
293 : length in bits with the following order:
294 : [0.0, 0.1, -0.1, 0.2, -0.2, 0.3, -0.3, 0.4, -0.4] */
295 : /* Bit rate truncation */
296 8354 : while ( res_index + 1 + *nb_bits > nr_of_sid_stereo_bits && res_index > 0 )
297 : {
298 0 : res_index = max( 0, res_index - 2 ); /* Reduce step by one, keeping sign. */
299 : }
300 : /* Write residual index to bitstream */
301 8354 : if ( res_index + 1 + *nb_bits <= nr_of_sid_stereo_bits ) /* If the bit limit is reached, res_index = 0 is assumed for remaining indices */
302 : {
303 8354 : *nb_bits += write_GR0( hBstr, IND_STEREO_DFT_SID_COH, &res_index, 1 );
304 : }
305 :
306 : /* Reconstruct */
307 8354 : res_index = dft_cng_coh_u2i[res_index];
308 8354 : pred_err = usdequant( res_index, -0.4f, 0.1f );
309 8354 : cohBandq[b] = pred + pred_err; /* Store for intra-frame prediction */
310 8354 : if ( cohBandq[b] > 1 )
311 : {
312 0 : cohBandq[b] = 1;
313 : }
314 8354 : else if ( cohBandq[b] < 0 )
315 : {
316 146 : cohBandq[b] = 0;
317 : }
318 :
319 8354 : mem_cohBand[b] = cohBandq[b]; /* Update memory for next frame */
320 8354 : pred = 0;
321 : }
322 : }
323 :
324 : /* Zero pad up to max number of bits to get constant bitrate */
325 25680 : for ( k = *nb_bits; k < nr_of_sid_stereo_bits; k++ )
326 : {
327 24235 : push_next_indice( hBstr, zeropad, 1 );
328 24235 : ( *nb_bits )++;
329 : }
330 :
331 :
332 1445 : return;
333 : }
334 :
335 :
336 : /*-------------------------------------------------------------------------
337 : * stereo_dft_cng_side_gain()
338 : *
339 : * Calculate CNG side gain
340 : *-------------------------------------------------------------------------*/
341 :
342 10351 : void stereo_dft_cng_side_gain(
343 : STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo handle */
344 : STEREO_CNG_ENC_HANDLE hStereoCng, /* i/o: Stereo CNG data structure */
345 : const int32_t core_brate, /* i : core bitrate */
346 : const int32_t last_core_brate, /* i : last core bitrate */
347 : const int16_t bwidth /* i : audio band-width */
348 : )
349 : {
350 : int16_t b;
351 : int16_t sgSum;
352 : int16_t band_limits_full[STEREO_DFT_BAND_MAX + 1];
353 : float prev_weight;
354 : int16_t NFFT_inner;
355 : int16_t nbands_full;
356 : float tmp;
357 :
358 10351 : NFFT_inner = ( STEREO_DFT_N_MAX_ENC * inner_frame_tbl[bwidth] ) / L_FRAME48k;
359 10351 : nbands_full = hStereoDft->nbands;
360 :
361 : /* Calculate side gain average. First average in an inactive period */
362 : /* uses a weighted sum of the current average and the one from the */
363 : /* previous inactive segment */
364 :
365 : /* Inactive frame => Update both sets of averages */
366 105887 : for ( b = 0; b < nbands_full; b++ )
367 : {
368 95536 : hStereoCng->sg_average[b] += hStereoDft->sidSideGain[b];
369 : }
370 10351 : hStereoCng->sg_average_counter++;
371 :
372 10351 : hStereoCng->cng_counter++;
373 10351 : hStereoCng->cng_counter = min( hStereoCng->cng_counter, STEREO_DFT_SG_ACT_CNT_MAX );
374 :
375 10351 : if ( core_brate == SID_2k40 )
376 : {
377 : /* SID frame */
378 1519 : if ( last_core_brate == FRAME_NO_DATA || hStereoCng->first_SID )
379 : {
380 : /* If first ever SID frame or not the first SID in an inactive segment */
381 : /* Calculate average only based on current sg_average */
382 : /* Copy current sum to previous */
383 11837 : for ( b = 0; b < hStereoDft->nbands; b++ )
384 : {
385 10678 : hStereoCng->prev_sg_average[b] = hStereoCng->sg_average[b];
386 10678 : hStereoCng->sg_average[b] = hStereoCng->sg_average[b] / (float) hStereoCng->sg_average_counter;
387 : }
388 :
389 1159 : hStereoCng->prev_sg_average_counter = hStereoCng->sg_average_counter;
390 : }
391 : else
392 : {
393 : /* If first SID in a new inactive segment */
394 : /* Calculate weighting factor based on the time since the last inactive segment */
395 360 : prev_weight = 0.8f * (float) ( STEREO_DFT_SG_ACT_CNT_MAX - hStereoCng->sg_active_cnt ) / (float) STEREO_DFT_SG_ACT_CNT_MAX + 0.2f;
396 :
397 : /* Calculate weighted average between prev and current sg */
398 : /* Set prev_sg sum to current. */
399 3785 : for ( b = 0; b < hStereoDft->nbands; b++ )
400 : {
401 3425 : tmp = hStereoCng->sg_average[b];
402 3425 : hStereoCng->sg_average[b] = ( hStereoCng->sg_average[b] + prev_weight * hStereoCng->prev_sg_average[b] ) / ( (float) hStereoCng->sg_average_counter + prev_weight * (float) hStereoCng->prev_sg_average_counter );
403 3425 : hStereoCng->prev_sg_average[b] = tmp;
404 : }
405 360 : hStereoCng->prev_sg_average_counter = hStereoCng->sg_average_counter;
406 : }
407 :
408 : /* Use coarse band partitioning in inactive frames */
409 : /* Rescale bands to the coarser partitioning taking the band size into account */
410 1519 : mvs2s( hStereoDft->band_limits, band_limits_full, STEREO_DFT_BAND_MAX + 1 );
411 1519 : hStereoDft->nbands = stereo_dft_band_config( hStereoDft->band_limits, hStereoDft->hConfig->band_res, min( STEREO_DFT_N_32k_ENC, NFFT_inner ), ENC );
412 1519 : if ( nbands_full > hStereoDft->nbands + 1 )
413 : {
414 5981 : for ( b = 0; b < hStereoDft->nbands; b++ )
415 : {
416 5104 : hStereoDft->sidSideGain[b] = hStereoCng->sg_average[2 * b] * ( band_limits_full[2 * b + 1] - band_limits_full[2 * b] );
417 5104 : sgSum = band_limits_full[2 * b + 1] - band_limits_full[2 * b];
418 5104 : if ( ( 2 * b + 1 ) < nbands_full )
419 : {
420 5091 : hStereoDft->sidSideGain[b] += hStereoCng->sg_average[2 * b + 1] * ( band_limits_full[2 * b + 2] - band_limits_full[2 * b + 1] );
421 5091 : sgSum += band_limits_full[2 * b + 2] - band_limits_full[2 * b + 1];
422 : }
423 5104 : hStereoDft->sidSideGain[b] = hStereoDft->sidSideGain[b] / sgSum;
424 5104 : stereo_dft_quantize_res_gains( &hStereoDft->sidSideGain[b], NULL, NULL, NULL, hStereoDft->side_gain_index_EC + b, NULL );
425 : }
426 : }
427 : else
428 : {
429 4336 : for ( b = 0; b < hStereoDft->nbands; b++ )
430 : {
431 3694 : stereo_dft_quantize_res_gains( &hStereoCng->sg_average[b], NULL, NULL, NULL, hStereoDft->side_gain_index_EC + b, NULL );
432 : }
433 : }
434 : /* Restart SID avg after sending SID */
435 1519 : hStereoCng->sg_average_counter = 0;
436 1519 : set_zero( hStereoCng->sg_average, STEREO_DFT_BAND_MAX );
437 : }
438 : else
439 : {
440 90265 : for ( b = 0; b < nbands_full; b++ )
441 : {
442 81433 : hStereoCng->prev_sg_average[b] += hStereoDft->sidSideGain[b];
443 : }
444 :
445 8832 : hStereoCng->prev_sg_average_counter++;
446 : }
447 :
448 10351 : hStereoCng->sg_active_cnt = 0;
449 10351 : hStereoCng->first_SID_after_TD = 0;
450 :
451 10351 : return;
452 : }
453 :
454 :
455 : /*---------------------------------------------------------------
456 : * stereo_enc_cng_init()
457 : *
458 : * Initializes counters and averages
459 : * ---------------------------------------------------------------*/
460 :
461 57 : void stereo_enc_cng_init(
462 : STEREO_CNG_ENC_HANDLE hStereoCng /* i/o: stereo CNG encoder structure */
463 : )
464 : {
465 57 : hStereoCng->sg_average_counter = 0;
466 57 : set_zero( hStereoCng->sg_average, STEREO_DFT_BAND_MAX );
467 57 : hStereoCng->prev_sg_average_counter = 0;
468 57 : set_zero( hStereoCng->prev_sg_average, STEREO_DFT_BAND_MAX );
469 57 : hStereoCng->sg_active_cnt = 0;
470 57 : hStereoCng->first_SID = 1;
471 57 : set_f( hStereoCng->mem_cohBand, 0.5f, STEREO_DFT_BAND_MAX / 2 );
472 57 : set_zero( hStereoCng->prev_cohBand, 2 * ( STEREO_DFT_BAND_MAX / 2 ) );
473 57 : hStereoCng->td_active = 0;
474 57 : hStereoCng->first_SID_after_TD = 1;
475 57 : hStereoCng->cng_counter = 0;
476 :
477 57 : return;
478 : }
479 :
480 :
481 : /*-------------------------------------------------------------------------
482 : * stereo_cng_upd_counters()
483 : *
484 : * Update Stereo CNG counters
485 : *-------------------------------------------------------------------------*/
486 :
487 21617 : void stereo_cng_upd_counters(
488 : STEREO_CNG_ENC_HANDLE hStereoCng, /* i/o: Stereo CNG data structure */
489 : const int32_t element_mode, /* i : element mode */
490 : const int16_t nbands, /* i : Number of bands in active */
491 : const float sidSideGain[], /* i : SID side gains */
492 : const int16_t burst_ho_count, /* i : Hang-over count */
493 : int16_t *coh_fade_counter /* i : Coherence fade counter */
494 : )
495 : {
496 : int16_t b;
497 :
498 : /* Update sg avg in hangover frames, reset in active frames */
499 21617 : if ( burst_ho_count > 0 && element_mode == IVAS_CPE_DFT )
500 : {
501 13916 : for ( b = 0; b < nbands; b++ )
502 : {
503 12537 : hStereoCng->sg_average[b] += sidSideGain[b];
504 : }
505 1379 : hStereoCng->sg_average_counter++;
506 : }
507 : else
508 : {
509 20238 : hStereoCng->sg_average_counter = 0;
510 20238 : set_zero( hStereoCng->sg_average, STEREO_DFT_BAND_MAX );
511 : }
512 :
513 : /* Increment active counter, stop at max value */
514 21617 : hStereoCng->sg_active_cnt++;
515 21617 : hStereoCng->sg_active_cnt = min( hStereoCng->sg_active_cnt, STEREO_DFT_SG_ACT_CNT_MAX );
516 :
517 21617 : if ( hStereoCng->sg_active_cnt > STEREO_DFT_CNG_ITD_CNT )
518 : {
519 19702 : hStereoCng->cng_counter = 0;
520 : }
521 :
522 21617 : if ( element_mode == IVAS_CPE_DFT )
523 : {
524 19952 : *coh_fade_counter = 0;
525 : }
526 21617 : return;
527 : }
|