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_fx.h"
40 : #include "ivas_cnst.h"
41 : #include "ivas_rom_com.h"
42 : #include "wmc_auto.h"
43 : #include "ivas_prot_fx.h"
44 :
45 :
46 : /*-------------------------------------------------------------------
47 : * Local constants
48 : *-------------------------------------------------------------------*/
49 :
50 : #define COH_FADE_MAX 4
51 : #define COH_FADE_UPDATES 2
52 :
53 :
54 : /*---------------------------------------------------------------
55 : * stereo_dft_enc_sid_calc_coh()
56 : *
57 : * Encodes the coherence in SID frames
58 : * ---------------------------------------------------------------*/
59 1449 : void stereo_dft_enc_sid_calc_coh_fx(
60 : STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo handle */
61 : Word32 prev_cohBand[2 * ( STEREO_DFT_BAND_MAX / 2 )], /* i/o: Previous coherence Q31 */
62 : Word16 *td_active, /* i/o: TD stereo mode indicator */
63 : Word16 *first_SID, /* i/o: First SID indicator */
64 : Word32 *cohBand /* i/o: Coherence per band Q31 */
65 : )
66 : {
67 : Word16 b, k;
68 : Word32 coh_weight;
69 : Word16 coh_weight_e;
70 : Word32 coh_weight_sum;
71 : Word16 coh_weight_sum_e;
72 : Word32 xspec_scale;
73 : Word32 L_tmp1, L_tmp2, L_tmp3;
74 : Word16 L_tmp1_e, L_tmp2_e, L_tmp3_e;
75 : Word64 W_tmp;
76 : Word16 W_tmp_q;
77 : // Word16 prev_cohBand_e[2 * (STEREO_DFT_BAND_MAX / 2)];
78 : Word16 cohBand_e[STEREO_DFT_BAND_MAX / 2];
79 : /* Cluster the coherence into bands using a weighted average. The coherence is weighted with the energy spectrum of the
80 : mixdown signal. */
81 9827 : FOR( b = 0; b < hStereoDft->nbands; b++ )
82 : {
83 8378 : cohBand[b] = 0;
84 8378 : move32();
85 8378 : cohBand_e[b] = 0;
86 8378 : move16();
87 8378 : coh_weight_sum = 0;
88 8378 : move32();
89 8378 : coh_weight_sum_e = 0;
90 8378 : move16();
91 :
92 8378 : test();
93 8378 : IF( hStereoDft->coh_fade_counter == 0 && !*first_SID )
94 : {
95 223902 : FOR( k = hStereoDft->band_limits[b]; k < hStereoDft->band_limits[b + 1]; k++ )
96 : {
97 : // 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 ) );
98 221704 : W_tmp = W_mult_32_32( hStereoDft->Spd_L_smooth_fx[k], hStereoDft->Spd_R_smooth_fx[k] );
99 221704 : W_tmp_q = W_norm( W_tmp );
100 221704 : L_tmp1 = W_extract_h( W_shl( W_tmp, W_tmp_q ) );
101 221704 : L_tmp1_e = sub( add( hStereoDft->Spd_L_smooth_fx_e, hStereoDft->Spd_R_smooth_fx_e ), W_tmp_q );
102 221704 : L_tmp2 = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hStereoDft->xspec_smooth_fx[2 * k], hStereoDft->xspec_smooth_fx[2 * k] ), shl( hStereoDft->xspec_smooth_fx_e[2 * k], 1 ), Mpy_32_32( hStereoDft->xspec_smooth_fx[2 * k + 1], hStereoDft->xspec_smooth_fx[2 * k + 1] ), shl( hStereoDft->xspec_smooth_fx_e[2 * k + 1], 1 ), &L_tmp2_e );
103 221704 : L_tmp2 = BASOP_Util_Add_Mant32Exp( L_tmp2, L_tmp2_e, EPSILON_FX_M, EPSILON_FX_E, &L_tmp2_e );
104 221704 : L_tmp3 = BASOP_Util_Divide3232_Scale_newton( L_tmp1, L_tmp2, &L_tmp3_e );
105 221704 : L_tmp3_e = add( L_tmp3_e, sub( L_tmp1_e, L_tmp2_e ) );
106 221704 : L_tmp3 = Mpy_32_32( prev_cohBand[b], L_tmp3 );
107 221704 : xspec_scale = Sqrt32( L_tmp3, &L_tmp3_e );
108 : // xspec_scale = L_shl(xspec_scale, L_tmp3_e);//Q31
109 :
110 221704 : hStereoDft->xspec_smooth_fx[2 * k] = Mpy_32_32( hStereoDft->xspec_smooth_fx[2 * k], xspec_scale ); // Q(31-(xspec_smooth_fx_e+tmp3_e))
111 221704 : move32();
112 221704 : hStereoDft->xspec_smooth_fx_e[2 * k] = add( hStereoDft->xspec_smooth_fx_e[2 * k], L_tmp3_e );
113 221704 : move16();
114 221704 : hStereoDft->xspec_smooth_fx[2 * k + 1] = Mpy_32_32( hStereoDft->xspec_smooth_fx[2 * k + 1], xspec_scale ); // Q(31-(xspec_smooth_fx_e+tmp3_e))
115 221704 : move32();
116 221704 : hStereoDft->xspec_smooth_fx_e[2 * k + 1] = add( hStereoDft->xspec_smooth_fx_e[2 * k + 1], L_tmp3_e );
117 221704 : move16();
118 : }
119 :
120 2198 : cohBand[b] = prev_cohBand[b];
121 2198 : move32();
122 : }
123 : ELSE
124 : {
125 609267 : FOR( k = hStereoDft->band_limits[b]; k < hStereoDft->band_limits[b + 1]; k++ )
126 : {
127 : // coh_weight = hStereoDft->DFT[0][2 * k] * hStereoDft->DFT[0][2 * k] + hStereoDft->DFT[0][2 * k + 1] * hStereoDft->DFT[0][2 * k + 1];
128 603087 : W_tmp = W_add( W_mult_32_32( hStereoDft->DFT_fx[0][2 * k], hStereoDft->DFT_fx[0][2 * k] ), W_mult_32_32( hStereoDft->DFT_fx[0][2 * k + 1], hStereoDft->DFT_fx[0][2 * k + 1] ) );
129 603087 : W_tmp_q = W_norm( W_tmp );
130 603087 : coh_weight = W_extract_h( W_shl( W_tmp, W_tmp_q ) );
131 603087 : coh_weight_e = sub( shl( hStereoDft->DFT_fx_e[0], 1 ), W_tmp_q ); // 31 - dft_e*2 + W_tmp_q
132 :
133 : // 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 );
134 603087 : L_tmp1 = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hStereoDft->xspec_smooth_fx[2 * k], hStereoDft->xspec_smooth_fx[2 * k] ), shl( hStereoDft->xspec_smooth_fx_e[2 * k], 1 ), Mpy_32_32( hStereoDft->xspec_smooth_fx[2 * k + 1], hStereoDft->xspec_smooth_fx[2 * k + 1] ), shl( hStereoDft->xspec_smooth_fx_e[2 * k + 1], 1 ), &L_tmp1_e );
135 603087 : W_tmp = W_mult_32_32( hStereoDft->Spd_L_smooth_fx[k], hStereoDft->Spd_R_smooth_fx[k] );
136 603087 : W_tmp_q = W_norm( W_tmp );
137 603087 : L_tmp2 = W_extract_h( W_shl( W_tmp, W_tmp_q ) );
138 603087 : L_tmp2_e = sub( add( hStereoDft->Spd_L_smooth_fx_e, hStereoDft->Spd_R_smooth_fx_e ), W_tmp_q );
139 603087 : L_tmp2 = BASOP_Util_Add_Mant32Exp( L_tmp2, L_tmp2_e, EPSILON_FX_M, EPSILON_FX_E, &L_tmp2_e );
140 603087 : L_tmp3 = BASOP_Util_Divide3232_Scale_newton( L_tmp1, L_tmp2, &L_tmp3_e );
141 603087 : L_tmp3_e = add( L_tmp3_e, sub( L_tmp1_e, L_tmp2_e ) );
142 603087 : L_tmp3 = Mpy_32_32( coh_weight, L_tmp3 );
143 603087 : L_tmp3_e = add( coh_weight_e, L_tmp3_e );
144 603087 : cohBand[b] = BASOP_Util_Add_Mant32Exp( cohBand[b], cohBand_e[b], L_tmp3, L_tmp3_e, &cohBand_e[b] );
145 603087 : move32();
146 :
147 : // coh_weight_sum += coh_weight;
148 603087 : coh_weight_sum = BASOP_Util_Add_Mant32Exp( coh_weight_sum, coh_weight_sum_e, coh_weight, coh_weight_e, &coh_weight_sum_e );
149 : }
150 6180 : IF( coh_weight_sum > 0 )
151 : {
152 : // cohBand[b] = cohBand[b] / coh_weight_sum;
153 6153 : cohBand[b] = BASOP_Util_Divide3232_Scale_newton( cohBand[b], coh_weight_sum, &L_tmp1_e );
154 6153 : move32();
155 6153 : cohBand_e[b] = add( L_tmp1_e, sub( cohBand_e[b], coh_weight_sum_e ) );
156 6153 : move16();
157 6153 : cohBand[b] = L_shl_sat( cohBand[b], cohBand_e[b] ); // Q31: value does not exceed 1.0
158 6153 : move32();
159 : }
160 : }
161 : }
162 :
163 1449 : IF( *first_SID )
164 : {
165 27 : Copy32( cohBand, prev_cohBand, hStereoDft->nbands );
166 27 : Copy32( prev_cohBand, &( prev_cohBand[STEREO_DFT_BAND_MAX / 2] ), hStereoDft->nbands );
167 27 : *first_SID = 0;
168 27 : move32();
169 : }
170 :
171 1449 : test();
172 1449 : test();
173 1449 : IF( LT_16( hStereoDft->coh_fade_counter, COH_FADE_MAX ) && ( *td_active || LT_16( hStereoDft->currentNumUpdates, COH_FADE_UPDATES ) ) )
174 : {
175 224 : FOR( b = 0; b < hStereoDft->nbands; b++ )
176 : {
177 : // cohBand[b] = ( cohBand[b] * hStereoDft->coh_fade_counter + prev_cohBand[b] * ( COH_FADE_MAX - hStereoDft->coh_fade_counter ) ) / COH_FADE_MAX;
178 191 : SWITCH( hStereoDft->coh_fade_counter )
179 : {
180 191 : case 0:
181 191 : cohBand[b] = prev_cohBand[b];
182 191 : move32();
183 191 : BREAK;
184 0 : case 1:
185 0 : cohBand[b] = L_add( L_shr( cohBand[b], 2 ), Mpy_32_32( prev_cohBand[b], 1610612736 /*3/4*/ ) );
186 0 : move32();
187 0 : BREAK;
188 0 : case 2:
189 0 : cohBand[b] = L_add( L_shr( cohBand[b], 1 ), L_shr( prev_cohBand[b], 1 ) );
190 0 : move32();
191 0 : BREAK;
192 0 : case 3:
193 0 : cohBand[b] = L_add( Mpy_32_32( cohBand[b], 1610612736 /*3/4*/ ), L_shr( prev_cohBand[b], 2 ) );
194 0 : move32();
195 0 : BREAK;
196 0 : default:
197 : assert( "unexpected hStereoDft->coh_fade_counter value" );
198 0 : BREAK;
199 : }
200 : }
201 33 : hStereoDft->coh_fade_counter = add( hStereoDft->coh_fade_counter, 1 );
202 33 : IF( hStereoDft->coh_fade_counter > 0 )
203 : {
204 33 : Copy32( &prev_cohBand[STEREO_DFT_BAND_MAX / 2], prev_cohBand, hStereoDft->nbands );
205 : }
206 33 : Copy32( cohBand, &prev_cohBand[STEREO_DFT_BAND_MAX / 2], hStereoDft->nbands );
207 : }
208 : ELSE
209 : {
210 1416 : IF( hStereoDft->coh_fade_counter > 0 )
211 : {
212 1046 : Copy32( &prev_cohBand[STEREO_DFT_BAND_MAX / 2], prev_cohBand, hStereoDft->nbands );
213 : }
214 1416 : Copy32( cohBand, &prev_cohBand[STEREO_DFT_BAND_MAX / 2], hStereoDft->nbands );
215 1416 : hStereoDft->coh_fade_counter = COH_FADE_MAX;
216 1416 : move16();
217 1416 : *td_active = 0;
218 1416 : move16();
219 : }
220 :
221 1449 : return;
222 : }
223 :
224 : /*---------------------------------------------------------------
225 : * stereo_dft_enc_sid_coh()
226 : *
227 : * Encodes the coherence in SID frames
228 : * ---------------------------------------------------------------*/
229 :
230 1449 : void stereo_dft_enc_sid_coh_fx(
231 : BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */
232 : Word32 *mem_cohBand, /* i/o: Coherence memory Q31 */
233 : const Word16 nbands, /* i : number of DFT stereo bands */
234 : Word16 *nb_bits, /* i/o: number of bits written */
235 : Word32 *cohBand /* i/o: Coherence per band Q31 */
236 : )
237 : {
238 : Word16 b, k;
239 : Word16 zeropad;
240 : Word16 nr_of_sid_stereo_bits;
241 : Word16 coh_pred_index;
242 : Word64 min_pred_err;
243 : Word16 pred_err; // Q13
244 : Word16 res_index;
245 : Word16 i;
246 : Word32 tmp;
247 : const Word16 *pptr;
248 : Word16 pred; // Q13
249 : Word16 cohBandq[STEREO_DFT_BAND_MAX / 2]; /* Reconstructed coherence values for intra-frame prediction Q15 */
250 : const Word16 *alphaptr;
251 : Word16 nbbits_test;
252 : Word16 prev_nbbits_test;
253 : Word16 alpha_step;
254 : Word16 alpha_level;
255 : Word16 n;
256 :
257 1449 : nr_of_sid_stereo_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS;
258 1449 : move16();
259 1449 : zeropad = 0;
260 1449 : move16();
261 :
262 : /* Encode coherence vector. Find best fixed predictor by minimizing prediction error on input vector.
263 : The prediction is formed by a linear combination of the previous values
264 : in the vector. Hence, prediction is only done for coefficient 1 and up.
265 : If not enough bits for at least one bit for encoding prediction
266 : residual then skip the coding and write zeroes to the bitstream if needed.
267 : In this case the decoder will set alpha to 0, i.e. reuse previous coherence */
268 :
269 1449 : IF( sub( sub( nr_of_sid_stereo_bits, *nb_bits ), STEREO_DFT_N_COH_ALPHA_BITS + STEREO_DFT_PRED_NBITS ) > 0 )
270 : {
271 1449 : min_pred_err = 134217728000000; // 1e6 in Q27
272 1449 : move64();
273 1449 : coh_pred_index = -1;
274 1449 : move16();
275 1449 : pptr = dft_cng_coh_pred_fx[0]; // Q13
276 7245 : FOR( k = 0; k < STEREO_DFT_N_COH_PRED; k++ )
277 : {
278 5796 : Word64 pred_err64 = 0;
279 5796 : move64();
280 33512 : 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) */
281 : {
282 27716 : Word64 pred64 = 0;
283 27716 : move64();
284 108336 : FOR( i = 0; i < b; i++ )
285 : {
286 : // pred += ( *pptr++ ) * cohBand[i];
287 80620 : pred64 = W_mac_32_16( pred64, cohBand[i], *pptr++ ); // Q45 (31+13+1)
288 : }
289 27716 : tmp = L_sub( L_shr( cohBand[b], 18 ), W_extract_h( pred64 ) ); // Q13
290 : // pred_err += tmp * tmp;
291 27716 : pred_err64 = W_mac_32_32( pred_err64, tmp, tmp ); // Q27
292 : }
293 : // if ( pred_err < min_pred_err ) /* Store best candidate */
294 5796 : IF( LT_64( pred_err64, min_pred_err ) ) /* Store best candidate */
295 : {
296 3121 : min_pred_err = pred_err64; // Q27
297 3121 : move64();
298 3121 : coh_pred_index = k;
299 3121 : move16();
300 : }
301 : }
302 :
303 1449 : push_next_indice( hBstr, coh_pred_index, STEREO_DFT_PRED_NBITS ); /* Write selected predictor to bitstream */
304 1449 : ( *nb_bits ) = add( *nb_bits, STEREO_DFT_PRED_NBITS );
305 1449 : move16();
306 :
307 : /* Pick two different alphas (one low and one high) as a function
308 : of the number of available bits. */
309 1449 : alpha_step = 0;
310 1449 : move16();
311 7245 : FOR( i = 0; i < STEREO_DFT_N_COH_ALPHA_STEPS - 1; i++ )
312 : {
313 5796 : IF( GT_16( sub( sub( nr_of_sid_stereo_bits, *nb_bits ), STEREO_DFT_N_COH_ALPHA_BITS ), dft_cng_coh_alpha_start[i] ) )
314 : {
315 5796 : alpha_step = add( i, 1 );
316 : }
317 : }
318 :
319 : /* Calculate the number of encoded bits. */
320 1449 : alphaptr = dft_cng_alpha_bits_fx[alpha_step];
321 1449 : alpha_level = 0;
322 1449 : move16();
323 1449 : prev_nbbits_test = 100;
324 1449 : move16();
325 4347 : FOR( i = 0; i < STEREO_DFT_N_COH_ALPHA_LEVELS; i++ )
326 : {
327 2898 : nbbits_test = 0;
328 2898 : move16();
329 2898 : pptr = dft_cng_coh_pred_fx[coh_pred_index]; // Q13
330 2898 : pred = 3277 /*0.4f*/;
331 2898 : move16();
332 19654 : FOR( b = 0; b < nbands; b++ )
333 : {
334 57066 : FOR( n = 0; n < b; n++ )
335 : {
336 : // pred += ( *pptr++ ) * cohBandq[n];
337 40310 : pred = add( pred, mult_r( cohBandq[n], *pptr++ ) ); // Q13
338 : }
339 :
340 : // pred = ( *alphaptr ) * pred + ( 1 - ( *alphaptr ) ) * mem_cohBand[b];
341 16756 : pred = add( mult_r( pred, *alphaptr ), shr_r( mult_r( extract_h( mem_cohBand[b] ), sub( MAX_16, *alphaptr ) ), 2 ) ); // Q13
342 16756 : pred_err = sub( shr_r( extract_h( cohBand[b] ), 2 ), pred ); // Q13
343 16756 : res_index = usquant_fx( pred_err, &pred_err, -3277 /*-0.4f in Q13*/, 410 /*0.1f in Q12*/, 9 );
344 16756 : res_index = dft_cng_coh_i2u[res_index];
345 16756 : nbbits_test = add( nbbits_test, add( res_index, 1 ) );
346 16756 : res_index = dft_cng_coh_u2i[res_index];
347 16756 : pred_err = usdequant_fx( res_index, -3277 /*-0.4f in Q13*/, 410 /*0.1f in Q12*/ ); // Q13
348 16756 : cohBandq[b] = add( pred, pred_err );
349 16756 : move16();
350 16756 : cohBandq[b] = shl_sat( cohBandq[b], 2 ); // Q15
351 16756 : move16();
352 16756 : if ( cohBandq[b] < 0 )
353 : {
354 249 : cohBandq[b] = 0;
355 249 : move16();
356 : }
357 16756 : pred = 0;
358 16756 : move16();
359 : }
360 :
361 2898 : if ( LT_16( nbbits_test, sub( sub( nr_of_sid_stereo_bits, *nb_bits ), STEREO_DFT_N_COH_ALPHA_BITS ) ) )
362 : {
363 2875 : alpha_level = i;
364 2875 : move16();
365 : }
366 :
367 2898 : if ( LT_16( nbbits_test, prev_nbbits_test ) )
368 : {
369 1526 : alpha_level = i;
370 1526 : move16();
371 : }
372 :
373 2898 : prev_nbbits_test = nbbits_test;
374 2898 : move16();
375 2898 : alphaptr++;
376 : }
377 :
378 : /* Do the actual encoding using the selected predictor and alpha */
379 1449 : push_next_indice( hBstr, alpha_level, STEREO_DFT_N_COH_ALPHA_BITS ); /* Write selected alpha index to bitstream */
380 1449 : ( *nb_bits ) += STEREO_DFT_N_COH_ALPHA_BITS;
381 1449 : move16();
382 1449 : alphaptr = &dft_cng_alpha_bits_fx[alpha_step][alpha_level];
383 1449 : pptr = dft_cng_coh_pred_fx[coh_pred_index]; /* Set pointer to selected predictor */
384 1449 : pred = 3277 /*0.4f in Q13*/;
385 1449 : move16();
386 9827 : FOR( b = 0; b < nbands; b++ )
387 : {
388 : /* Intra-frame prediction using quantized values */
389 28533 : FOR( i = 0; i < b; i++ )
390 : {
391 : // pred += ( *pptr++ ) * cohBandq[i];
392 20155 : pred = add( pred, mult_r( cohBandq[i], *pptr++ ) ); // Q13
393 : }
394 : /* Weighted intra/inter-frame prediction */
395 : // pred = ( *alphaptr ) * pred + ( 1 - ( *alphaptr ) ) * mem_cohBand[b];
396 8378 : pred = add( mult_r( pred, *alphaptr ), shr_r( mult_r( extract_h( mem_cohBand[b] ), sub( MAX_16, *alphaptr ) ), 2 ) ); // Q13
397 8378 : pred_err = sub( shr_r( extract_h( cohBand[b] ), 2 ), pred ); // Q13
398 :
399 8378 : res_index = usquant_fx( pred_err, &pred_err, -3277 /*-0.4f in Q13*/, 410 /*0.1f in Q12*/, 9 ); /* Quantize prediction residual */
400 8378 : res_index = dft_cng_coh_i2u[res_index]; /* Convert to unary codeword - res_index+1 now equal to codeword
401 : length in bits with the following order:
402 : [0.0, 0.1, -0.1, 0.2, -0.2, 0.3, -0.3, 0.4, -0.4] */
403 : /* Bit rate truncation */
404 8378 : WHILE( res_index + 1 + *nb_bits > nr_of_sid_stereo_bits && res_index > 0 )
405 : {
406 0 : test();
407 0 : res_index = s_max( 0, sub( res_index, 2 ) ); /* Reduce step by one, keeping sign. */
408 : }
409 : /* Write residual index to bitstream */
410 8378 : IF( LE_16( add( add( res_index, 1 ), *nb_bits ), nr_of_sid_stereo_bits ) ) /* If the bit limit is reached, res_index = 0 is assumed for remaining indices */
411 : {
412 8378 : *nb_bits = add( *nb_bits, write_GR0_fx( hBstr, IND_STEREO_DFT_SID_COH, &res_index, 1 ) );
413 8378 : move16();
414 : }
415 :
416 : /* Reconstruct */
417 8378 : res_index = dft_cng_coh_u2i[res_index];
418 8378 : move16();
419 8378 : pred_err = usdequant_fx( res_index, -3277 /*-0.4f in Q13*/, 410 /*0.1f in Q12*/ );
420 8378 : cohBandq[b] = add( pred, pred_err ); /* Store for intra-frame prediction */
421 8378 : move16();
422 8378 : cohBandq[b] = shl_sat( cohBandq[b], 2 ); // Q15
423 8378 : move16();
424 8378 : if ( cohBandq[b] < 0 )
425 : {
426 165 : cohBandq[b] = 0;
427 165 : move16();
428 : }
429 :
430 8378 : mem_cohBand[b] = L_deposit_h( cohBandq[b] ); /* Update memory for next frame Q31*/
431 8378 : move32();
432 8378 : pred = 0;
433 8378 : move16();
434 : }
435 : }
436 :
437 : /* Zero pad up to max number of bits to get constant bitrate */
438 23701 : FOR( k = *nb_bits; k < nr_of_sid_stereo_bits; k++ )
439 : {
440 22252 : push_next_indice( hBstr, zeropad, 1 );
441 22252 : ( *nb_bits ) = add( *nb_bits, 1 );
442 22252 : move16();
443 : }
444 :
445 :
446 1449 : return;
447 : }
448 :
449 : /*-------------------------------------------------------------------------
450 : * stereo_dft_cng_side_gain()
451 : *
452 : * Calculate CNG side gain
453 : *-------------------------------------------------------------------------*/
454 :
455 10307 : void stereo_dft_cng_side_gain_fx(
456 : STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo handle */
457 : STEREO_CNG_ENC_HANDLE hStereoCng, /* i/o: Stereo CNG data structure */
458 : const Word32 core_brate, /* i : core bitrate */
459 : const Word32 last_core_brate, /* i : last core bitrate */
460 : const Word16 bwidth /* i : audio band-width */
461 : )
462 : {
463 : Word16 b;
464 : Word16 sgSum;
465 : Word16 band_limits_full[STEREO_DFT_BAND_MAX + 1];
466 : Word16 prev_weight; // Q15
467 : Word16 NFFT_inner;
468 : Word16 nbands_full;
469 : Word32 tmp;
470 : Word16 tmp_16;
471 : Word16 tmp_e;
472 : Word64 W_tmp;
473 : Word16 W_tmp_q;
474 :
475 : // NFFT_inner = STEREO_DFT_N_MAX_ENC * inner_frame_tbl[bwidth] / L_FRAME48k;
476 10307 : NFFT_inner = shl( inner_frame_tbl[bwidth], 1 );
477 10307 : nbands_full = hStereoDft->nbands;
478 10307 : move16();
479 :
480 : /* Calculate side gain average. First average in an inactive period */
481 : /* uses a weighted sum of the current average and the one from the */
482 : /* previous inactive segment */
483 :
484 : /* Inactive frame => Update both sets of averages */
485 105234 : FOR( b = 0; b < nbands_full; b++ )
486 : {
487 : // hStereoCng->sg_average[b] += hStereoDft->sidSideGain[b];
488 94927 : hStereoCng->sg_average_fx[b] = L_add( hStereoCng->sg_average_fx[b], L_shr_r( hStereoDft->sidSideGain_fx[b], 5 ) );
489 94927 : move32();
490 : }
491 10307 : hStereoCng->sg_average_counter = add( hStereoCng->sg_average_counter, 1 );
492 10307 : move32();
493 :
494 10307 : hStereoCng->cng_counter = add( hStereoCng->cng_counter, 1 );
495 10307 : move16();
496 10307 : hStereoCng->cng_counter = s_min( hStereoCng->cng_counter, STEREO_DFT_SG_ACT_CNT_MAX );
497 10307 : move16();
498 :
499 10307 : IF( EQ_32( core_brate, SID_2k40 ) )
500 : {
501 : /* SID frame */
502 1523 : test();
503 1523 : IF( EQ_32( last_core_brate, FRAME_NO_DATA ) || hStereoCng->first_SID )
504 : {
505 : /* If first ever SID frame or not the first SID in an inactive segment */
506 : /* Calculate average only based on current sg_average */
507 : /* Copy current sum to previous */
508 11709 : FOR( b = 0; b < hStereoDft->nbands; b++ )
509 : {
510 10562 : hStereoCng->prev_sg_average_fx[b] = hStereoCng->sg_average_fx[b];
511 10562 : move32();
512 : // hStereoCng->sg_average[b] = hStereoCng->sg_average[b] / (float) hStereoCng->sg_average_counter;
513 10562 : hStereoCng->sg_average_fx[b] = BASOP_Util_Divide3232_Scale_newton( hStereoCng->sg_average_fx[b], hStereoCng->sg_average_counter, &tmp_e );
514 10562 : move32();
515 10562 : tmp_e = sub( tmp_e, 31 - 5 );
516 10562 : hStereoCng->sg_average_fx[b] = L_shl_r( hStereoCng->sg_average_fx[b], sub( tmp_e, 5 ) ); // Q31
517 10562 : move32();
518 : }
519 :
520 1147 : hStereoCng->prev_sg_average_counter = hStereoCng->sg_average_counter;
521 1147 : move16();
522 : }
523 : ELSE
524 : {
525 : /* If first SID in a new inactive segment */
526 : /* Calculate weighting factor based on the time since the last inactive segment */
527 : // prev_weight = 0.8f * (float) ( STEREO_DFT_SG_ACT_CNT_MAX - hStereoCng->sg_active_cnt ) / (float) STEREO_DFT_SG_ACT_CNT_MAX + 0.2f;
528 376 : tmp_16 = BASOP_Util_Divide1616_Scale( sub( STEREO_DFT_SG_ACT_CNT_MAX, hStereoCng->sg_active_cnt ), STEREO_DFT_SG_ACT_CNT_MAX, &tmp_e );
529 376 : prev_weight = add( shl( mult_r( 26214 /*0.8f*/, tmp_16 ), tmp_e ), 6554 /*0.2f*/ );
530 :
531 : /* Calculate weighted average between prev and current sg */
532 : /* Set prev_sg sum to current. */
533 3900 : FOR( b = 0; b < hStereoDft->nbands; b++ )
534 : {
535 3524 : tmp = hStereoCng->sg_average_fx[b];
536 3524 : move32();
537 : // 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 );
538 3524 : hStereoCng->sg_average_fx[b] = BASOP_Util_Divide3232_Scale_newton( L_add( hStereoCng->sg_average_fx[b], Mpy_32_16_1( hStereoCng->prev_sg_average_fx[b], prev_weight ) ), L_add( L_shl( hStereoCng->sg_average_counter, Q15 ), L_mult0( prev_weight, hStereoCng->prev_sg_average_counter ) ), &tmp_e );
539 3524 : move32();
540 3524 : tmp_e = sub( tmp_e, 16 - 5 );
541 3524 : hStereoCng->sg_average_fx[b] = L_shl_r( hStereoCng->sg_average_fx[b], sub( tmp_e, 5 ) ); // Q26
542 3524 : move32();
543 :
544 3524 : hStereoCng->prev_sg_average_fx[b] = tmp;
545 3524 : move32();
546 : }
547 376 : hStereoCng->prev_sg_average_counter = hStereoCng->sg_average_counter;
548 376 : move16();
549 : }
550 :
551 : /* Use coarse band partitioning in inactive frames */
552 : /* Rescale bands to the coarser partitioning taking the band size into account */
553 1523 : Copy( hStereoDft->band_limits, band_limits_full, STEREO_DFT_BAND_MAX + 1 );
554 1523 : hStereoDft->nbands = stereo_dft_band_config_fx( hStereoDft->band_limits, hStereoDft->hConfig->band_res, s_min( STEREO_DFT_N_32k_ENC, NFFT_inner ), ENC );
555 1523 : move16();
556 1523 : IF( GT_16( nbands_full, add( hStereoDft->nbands, 1 ) ) )
557 : {
558 5939 : FOR( b = 0; b < hStereoDft->nbands; b++ )
559 : {
560 : // hStereoDft->sidSideGain[b] = hStereoCng->sg_average[2 * b] * ( band_limits_full[2 * b + 1] - band_limits_full[2 * b] );
561 5068 : W_tmp = W_shl( W_mult_32_32( hStereoCng->sg_average_fx[2 * b], sub( band_limits_full[2 * b + 1], band_limits_full[2 * b] ) ), 5 ); // Q31
562 5068 : sgSum = sub( band_limits_full[2 * b + 1], band_limits_full[2 * b] );
563 : // if ( ( 2 * b + 1 ) < nbands_full )
564 5068 : IF( LT_16( add( shl( b, 1 ), 1 ), nbands_full ) )
565 : {
566 : // hStereoDft->sidSideGain[b] += hStereoCng->sg_average[2 * b + 1] * ( band_limits_full[2 * b + 2] - band_limits_full[2 * b + 1] );
567 5055 : W_tmp = W_add( W_tmp, W_shl( W_mult_32_32( hStereoCng->sg_average_fx[2 * b + 1], sub( band_limits_full[2 * b + 2], band_limits_full[2 * b + 1] ) ), 5 ) ); // Q31
568 5055 : sgSum = add( sgSum, sub( band_limits_full[2 * b + 2], band_limits_full[2 * b + 1] ) );
569 : }
570 : // hStereoDft->sidSideGain[b] = hStereoDft->sidSideGain[b] / sgSum;
571 5068 : W_tmp_q = W_norm( W_tmp );
572 5068 : hStereoDft->sidSideGain_fx[b] = W_extract_h( W_shl( W_tmp, W_tmp_q ) );
573 5068 : move32();
574 5068 : hStereoDft->sidSideGain_fx[b] = BASOP_Util_Divide3232_Scale_newton( hStereoDft->sidSideGain_fx[b], sgSum, &tmp_e );
575 5068 : move32();
576 5068 : tmp_e = sub( tmp_e, W_tmp_q );
577 5068 : hStereoDft->sidSideGain_fx[b] = L_shl_sat( hStereoDft->sidSideGain_fx[b], tmp_e ); // Q31: saturation is fine since stereo_dft_quantize_res_gains_fx limits value to 1.0
578 5068 : move32();
579 5068 : stereo_dft_quantize_res_gains_fx( &hStereoDft->sidSideGain_fx[b], NULL, NULL, NULL, hStereoDft->side_gain_index_EC + b, NULL );
580 : }
581 : }
582 : ELSE
583 : {
584 : Word32 sg_average_fx_q31;
585 4406 : FOR( b = 0; b < hStereoDft->nbands; b++ )
586 : {
587 3754 : sg_average_fx_q31 = L_shl_sat( hStereoCng->sg_average_fx[b], 5 ); // Q31
588 3754 : stereo_dft_quantize_res_gains_fx( &sg_average_fx_q31, NULL, NULL, NULL, hStereoDft->side_gain_index_EC + b, NULL );
589 : }
590 : }
591 : /* Restart SID avg after sending SID */
592 1523 : hStereoCng->sg_average_counter = 0;
593 1523 : move16();
594 1523 : set_zero_fx( hStereoCng->sg_average_fx, STEREO_DFT_BAND_MAX );
595 : }
596 : ELSE
597 : {
598 89625 : FOR( b = 0; b < nbands_full; b++ )
599 : {
600 : // hStereoCng->prev_sg_average[b] += hStereoDft->sidSideGain[b];
601 80841 : hStereoCng->prev_sg_average_fx[b] = L_add( hStereoCng->prev_sg_average_fx[b], L_shr_r( hStereoDft->sidSideGain_fx[b], 5 ) ); // Q26
602 80841 : move32();
603 : }
604 :
605 8784 : hStereoCng->prev_sg_average_counter = add( hStereoCng->prev_sg_average_counter, 1 );
606 8784 : move16();
607 : }
608 :
609 10307 : hStereoCng->sg_active_cnt = 0;
610 10307 : move16();
611 10307 : hStereoCng->first_SID_after_TD = 0;
612 10307 : move16();
613 :
614 10307 : return;
615 : }
616 :
617 : /*---------------------------------------------------------------
618 : * stereo_enc_cng_init()
619 : *
620 : * Initializes counters and averages
621 : * ---------------------------------------------------------------*/
622 :
623 57 : void stereo_enc_cng_init_fx(
624 : STEREO_CNG_ENC_HANDLE hStereoCng /* i/o: stereo CNG encoder structure */
625 : )
626 : {
627 57 : hStereoCng->sg_average_counter = 0;
628 57 : move16();
629 57 : set32_fx( hStereoCng->sg_average_fx, 0, STEREO_DFT_BAND_MAX );
630 57 : hStereoCng->prev_sg_average_counter = 0;
631 57 : move16();
632 57 : set32_fx( hStereoCng->prev_sg_average_fx, 0, STEREO_DFT_BAND_MAX );
633 57 : hStereoCng->sg_active_cnt = 0;
634 57 : move16();
635 57 : hStereoCng->first_SID = 1;
636 57 : move16();
637 57 : set32_fx( hStereoCng->mem_cohBand_fx, ONE_IN_Q30, STEREO_DFT_BAND_MAX / 2 );
638 57 : set32_fx( hStereoCng->prev_cohBand_fx, 0, 2 * ( STEREO_DFT_BAND_MAX / 2 ) );
639 57 : hStereoCng->td_active = 0;
640 57 : move16();
641 57 : hStereoCng->first_SID_after_TD = 1;
642 57 : move16();
643 57 : hStereoCng->cng_counter = 0;
644 57 : move16();
645 :
646 57 : return;
647 : }
648 :
649 :
650 : /*-------------------------------------------------------------------------
651 : * stereo_cng_upd_counters()
652 : *
653 : * Update Stereo CNG counters
654 : *-------------------------------------------------------------------------*/
655 21661 : void stereo_cng_upd_counters_fx(
656 : STEREO_CNG_ENC_HANDLE hStereoCng, /* i/o: Stereo CNG data structure */
657 : const Word32 element_mode, /* i : element mode */
658 : const Word16 nbands, /* i : Number of bands in active */
659 : const Word32 sidSideGain[], /* i : SID side gains Q31 */
660 : const Word16 burst_ho_count, /* i : Hang-over count */
661 : Word16 *coh_fade_counter /* i : Coherence fade counter */
662 : )
663 : {
664 : Word16 b;
665 :
666 : /* Update sg avg in hangover frames, reset in active frames */
667 21661 : test();
668 21661 : IF( burst_ho_count > 0 && EQ_32( element_mode, IVAS_CPE_DFT ) )
669 : {
670 13854 : FOR( b = 0; b < nbands; b++ )
671 : {
672 : // hStereoCng->sg_average[b] += sidSideGain[b];
673 12487 : hStereoCng->sg_average_fx[b] = L_add( hStereoCng->sg_average_fx[b], L_shr_r( sidSideGain[b], 5 ) ); // Q26
674 12487 : move32();
675 : }
676 1367 : hStereoCng->sg_average_counter = add( hStereoCng->sg_average_counter, 1 );
677 1367 : move16();
678 : }
679 : else
680 : {
681 20294 : hStereoCng->sg_average_counter = 0;
682 20294 : move16();
683 20294 : set_zero_fx( hStereoCng->sg_average_fx, STEREO_DFT_BAND_MAX );
684 : }
685 :
686 : /* Increment active counter, stop at max value */
687 21661 : hStereoCng->sg_active_cnt = add( hStereoCng->sg_active_cnt, 1 );
688 21661 : move16();
689 21661 : hStereoCng->sg_active_cnt = s_min( hStereoCng->sg_active_cnt, STEREO_DFT_SG_ACT_CNT_MAX );
690 21661 : move16();
691 :
692 21661 : IF( GT_16( hStereoCng->sg_active_cnt, STEREO_DFT_CNG_ITD_CNT ) )
693 : {
694 19757 : hStereoCng->cng_counter = 0;
695 19757 : move16();
696 : }
697 :
698 21661 : IF( EQ_32( element_mode, IVAS_CPE_DFT ) )
699 : {
700 19992 : *coh_fade_counter = 0;
701 19992 : move16();
702 : }
703 21661 : return;
704 : }
|