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.452 Aug 12, 2021. Version 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <stdint.h>
38 : #include <math.h>
39 : #include "options.h" /* Compilation switches */
40 : #include "cnst.h" /* Common constants */
41 : #include "rom_com.h" /* Static table prototypes */
42 : #include "prot_fx.h"
43 : #include "stl.h"
44 : #include "wmc_auto.h"
45 :
46 : /*-------------------------------------------------------------------*
47 : * Local constants
48 : *-------------------------------------------------------------------*/
49 :
50 : static Word16 VDQ_vec_fx( Word16 *Qvec_out_fx, const Word16 *mean_dic_fx, const Word16 *dic_fx, const Word16 index_fx, const Word16 vec_en_fx );
51 :
52 : /*========================================================================*/
53 : /* FUNCTION : void Comp_and_apply_gain_enc_fx */
54 : /*------------------------------------------------------------------------*/
55 : /* PURPOSE : Compute and apply the quantized per band gain */
56 : /*------------------------------------------------------------------------*/
57 : /* INPUT ARGUMENTS : */
58 : /* _ (Word16[]) Ener_per_bd_iQ : Target ener per band Q12 */
59 : /*------------------------------------------------------------------------*/
60 : /* INPUT/OUTPUT ARGUMENTS : */
61 : /* _ (Word16[]) exc_diffQ : Quantized excitation Qexc */
62 : /* _ (Word16[]) Ener_per_bd_yQ : Ener per band for norm vectori->Q12/o->Q2*/
63 : /*------------------------------------------------------------------------*/
64 : /* OUTPUT ARGUMENTS : */
65 : /* _ None */
66 : /*------------------------------------------------------------------------*/
67 :
68 : /*------------------------------------------------------------------------*/
69 : /* RETURN ARGUMENTS : */
70 : /* _ None */
71 : /*========================================================================*/
72 :
73 22 : void Comp_and_apply_gain_fx(
74 : Word16 exc_diffQ[], /* i/o: Quantized excitation */
75 : Word16 Ener_per_bd_iQ[], /* i : Target ener per band Q13 */
76 : Word16 Ener_per_bd_yQ[], /* i/o : Ener per band for norm vector i->Q13/o->Q13 */
77 : Word16 Mbands_gn, /* i : number of bands */
78 : const Word16 ReUseGain, /* i : Reuse the gain in Ener_per_bd_yQ */
79 : Word16 Qexc_diff,
80 : Word16 Q_exc )
81 : {
82 : Word16 i, i_band;
83 : Word16 StartBin, NB_Qbins;
84 : Word16 y_gain;
85 : Word16 L16, frac, exp1, tmp_exp;
86 : Word32 L32;
87 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
88 22 : Flag Overflow = 0;
89 22 : move32();
90 : #endif
91 :
92 : /* Recreate excitation for local synthesis and decoder */
93 22 : StartBin = 0;
94 22 : move16();
95 22 : NB_Qbins = 0;
96 22 : move16();
97 :
98 22 : tmp_exp = add( 14, sub( Q_exc, Qexc_diff ) ); /* In case of reuse, it can be computed outside the loop*/
99 374 : FOR( i_band = 0; i_band < Mbands_gn; i_band++ )
100 : {
101 352 : StartBin = add( StartBin, NB_Qbins );
102 352 : NB_Qbins = mfreq_bindiv_loc[i_band];
103 352 : move16();
104 352 : IF( EQ_16( ReUseGain, 1 ) )
105 : {
106 176 : y_gain = Ener_per_bd_yQ[i_band];
107 176 : move16();
108 :
109 2992 : FOR( i = StartBin; i < NB_Qbins + StartBin; i++ )
110 : {
111 2816 : L32 = L_shl_o( L_mult( exc_diffQ[i], y_gain ), tmp_exp, &Overflow ); /*Q_exc+16 */
112 2816 : exc_diffQ[i] = round_fx_o( L32, &Overflow ); /*Q_exc */
113 2816 : move16();
114 : }
115 : }
116 : ELSE
117 : {
118 : /*-----------------------------------------------------------------*
119 : * y_gain = pow(10.0, (Ener_per_bd_iQ[i_band]-Ener_per_bd_yQ[i_band]))
120 : * = pow(2, 3.321928*(Ener_per_bd_iQ[i_band]-Ener_per_bd_yQ[i_band]))
121 : *-----------------------------------------------------------------*/
122 176 : L16 = sub( Ener_per_bd_iQ[i_band], Ener_per_bd_yQ[i_band] ); /*Q12 */
123 176 : L32 = L_mult( L16, 27213 ); /* 3.321928 in Q13 -> Q26 */
124 176 : L32 = L_shr( L32, 10 ); /* From Q26 to Q16 */
125 176 : frac = L_Extract_lc( L32, &exp1 ); /* Extract exponent of gcode0 */
126 176 : y_gain = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
127 : /* output of Pow2() will be: */
128 : /* 16384 < Pow2() <= 32767 */
129 176 : Ener_per_bd_yQ[i_band] = shl_o( y_gain, sub( exp1, 13 ), &Overflow );
130 176 : move16(); /*Q1 */
131 176 : tmp_exp = add( add( exp1, 1 ), sub( Q_exc, Qexc_diff ) );
132 :
133 2992 : FOR( i = StartBin; i < NB_Qbins + StartBin; i++ )
134 : {
135 2816 : L32 = L_mult( exc_diffQ[i], y_gain ); /*Qexc_diff+15 */
136 2816 : exc_diffQ[i] = round_fx_o( L_shl_o( L32, tmp_exp, &Overflow ), &Overflow ); /*Q_exc */
137 2816 : move16();
138 : }
139 : }
140 : }
141 :
142 22 : return;
143 : }
144 :
145 86654 : void Comp_and_apply_gain_ivas_fx(
146 : Word16 exc_diffQ[], /* i/o: Quantized excitation */
147 : Word16 Ener_per_bd_iQ[], /* i : Target ener per band Q13 */
148 : Word16 Ener_per_bd_yQ[], /* i/o : Ener per band for norm vector i->Q13/o->Q13 */
149 : Word16 Mbands_gn, /* i : number of bands */
150 : const Word16 ReUseGain, /* i : Reuse the gain in Ener_per_bd_yQ */
151 : Word16 Qexc_diff,
152 : Word16 *Q_exc )
153 : {
154 : Word16 i, i_band;
155 : Word16 StartBin, NB_Qbins;
156 : Word16 y_gain;
157 : Word16 L16, frac, exp1, tmp_exp;
158 : Word32 L32;
159 : Word16 Q_exc_diffQ[L_FRAME16k];
160 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
161 86654 : Flag Overflow = 0;
162 86654 : move32();
163 : #endif
164 :
165 : /* Recreate excitation for local synthesis and decoder */
166 86654 : StartBin = 0;
167 86654 : move16();
168 86654 : NB_Qbins = 0;
169 86654 : move16();
170 :
171 86654 : tmp_exp = add( 14, sub( *Q_exc, Qexc_diff ) ); /* In case of reuse, it can be computed outside the loop*/
172 1493582 : FOR( i_band = 0; i_band < Mbands_gn; i_band++ )
173 : {
174 1406928 : StartBin = add( StartBin, NB_Qbins );
175 1406928 : NB_Qbins = mfreq_bindiv_loc[i_band];
176 1406928 : move16();
177 1406928 : IF( EQ_16( ReUseGain, 1 ) )
178 : {
179 701844 : y_gain = Ener_per_bd_yQ[i_band]; /*Q13*/
180 701844 : move16();
181 :
182 12096788 : FOR( i = StartBin; i < NB_Qbins + StartBin; i++ )
183 : {
184 11394944 : L32 = L_mult( exc_diffQ[i], y_gain ); /*Q_exc+16-tmp_exp */
185 11394944 : exc_diffQ[i] = round_fx_o( L32, &Overflow ); /*Q_exc-tmp_exp */
186 11394944 : move16();
187 11394944 : IF( exc_diffQ[i] )
188 : {
189 881457 : Q_exc_diffQ[i] = sub( *Q_exc, tmp_exp );
190 : }
191 : ELSE
192 : {
193 10513487 : Q_exc_diffQ[i] = *Q_exc;
194 : }
195 11394944 : move16();
196 : }
197 : }
198 : ELSE
199 : {
200 : /*-----------------------------------------------------------------*
201 : * y_gain = pow(10.0, (Ener_per_bd_iQ[i_band]-Ener_per_bd_yQ[i_band]))
202 : * = pow(2, 3.321928*(Ener_per_bd_iQ[i_band]-Ener_per_bd_yQ[i_band]))
203 : *-----------------------------------------------------------------*/
204 705084 : L16 = sub_sat( Ener_per_bd_iQ[i_band], Ener_per_bd_yQ[i_band] ); /*Q12 */
205 705084 : L32 = L_mult( L16, 27213 ); /* 3.321928 in Q13 -> Q26 */
206 705084 : L32 = L_shr( L32, 10 ); /* From Q26 to Q16 */
207 705084 : frac = L_Extract_lc( L32, &exp1 ); /* Extract exponent of gcode0 */
208 705084 : y_gain = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
209 : /* output of Pow2() will be: */
210 : /* 16384 < Pow2() <= 32767 */
211 705084 : Ener_per_bd_yQ[i_band] = shl_o( y_gain, sub( exp1, 13 ), &Overflow ); /*Q13*/
212 705084 : move16(); /*Q1 */
213 705084 : tmp_exp = add( add( exp1, 1 ), sub( *Q_exc, Qexc_diff ) );
214 :
215 12151996 : FOR( i = StartBin; i < NB_Qbins + StartBin; i++ )
216 : {
217 11446912 : L32 = L_mult( exc_diffQ[i], y_gain ); /*Qexc_diff+15 */
218 11446912 : exc_diffQ[i] = round_fx_o( L32, &Overflow ); /*Q_exc-tmp_exp */
219 11446912 : move16();
220 11446912 : IF( exc_diffQ[i] )
221 : {
222 10182445 : Q_exc_diffQ[i] = sub( *Q_exc, tmp_exp );
223 : }
224 : ELSE
225 : {
226 1264467 : Q_exc_diffQ[i] = *Q_exc;
227 : }
228 11446912 : move16();
229 : }
230 : }
231 : }
232 :
233 22928510 : FOR( i = 0; i < StartBin + NB_Qbins; i++ )
234 : {
235 22841856 : *Q_exc = s_min( *Q_exc, add( Q_exc_diffQ[i], norm_s( exc_diffQ[i] ) ) );
236 22841856 : move16();
237 : }
238 22928510 : FOR( i = 0; i < StartBin + NB_Qbins; i++ )
239 : {
240 22841856 : exc_diffQ[i] = shl( exc_diffQ[i], sub( *Q_exc, Q_exc_diffQ[i] ) ); /*Q_exc*/
241 22841856 : move16();
242 : }
243 :
244 86654 : return;
245 : }
246 :
247 :
248 : /*========================================================================*/
249 : /* FUNCTION : Ener_per_band_comp_fx() */
250 : /*------------------------------------------------------------------------*/
251 : /* PURPOSE : Compute the energy per band in log domain for quantization */
252 : /* purposes. */
253 : /* Loops are decomposed to accomodate the PVQ quantization */
254 : /*------------------------------------------------------------------------*/
255 : /* INPUT ARGUMENTS : */
256 : /* _ (Word16*) edct_table_128_fx : edct table Q15 */
257 : /* _ (Word16*) Q_exc_diff : input format of exc_diff */
258 : /*------------------------------------------------------------------------*/
259 : /* INPUT/OUTPUT ARGUMENTS : */
260 : /*------------------------------------------------------------------------*/
261 : /* OUTPUT ARGUMENTS : */
262 : /* _ (Word16[]) y_gain4 : Energy per band to quantize Q12 */
263 : /* _ (Word32*) etmp14 : Energy band 14 Q_exc_diff*2+1 */
264 : /* _ (Word32*) etmp15 : Energy band 15 Q_exc_diff*2+1 */
265 : /*------------------------------------------------------------------------*/
266 :
267 : /*------------------------------------------------------------------------*/
268 : /* RETURN ARGUMENTS : */
269 : /* _ None */
270 : /*========================================================================*/
271 :
272 3467814 : static Word16 Comp_band_log_ener( /* o : Band gain Q12 */
273 : const Word16 *pt_fx, /* i : Dct input Q_sc */
274 : const Word16 Len, /* i : Lenght en energy accumulation */
275 : const Word16 Q_sc, /* i : scaling of input */
276 : const Word16 E_sc /* i : Additional scaling factor for energy */
277 : )
278 : {
279 : Word32 L_tmp;
280 : Word16 e_tmp, f_tmp, tmp16, ener_exp;
281 3467814 : L_tmp = Calc_Energy_Autoscaled( pt_fx, Q_sc, Len, &ener_exp );
282 3467814 : e_tmp = norm_l( L_tmp );
283 3467814 : f_tmp = Log2_norm_lc( L_shl( L_tmp, e_tmp ) );
284 3467814 : e_tmp = sub( sub( add( 30, E_sc ), e_tmp ), ener_exp );
285 3467814 : L_tmp = Mpy_32_16( e_tmp, f_tmp, 19728 ); /* Q16 */ /*log10(2) in Q17 */
286 3467814 : tmp16 = round_fx( L_shl( L_tmp, 12 - 2 ) ); /* Q12 -1 is to compensate Q17 */
287 3467814 : return tmp16;
288 : }
289 :
290 10 : void Ener_per_band_comp_fx(
291 : const Word16 exc_diff_fx[], /* i : target signal Q_exc_diff */
292 : Word16 y_gain4_fx[], /* o : Energy per band to quantize Q12 */
293 : const Word16 Q_exc, /* i : frame length */
294 : const Word16 Mband, /* i : Max band */
295 : const Word16 Eflag /* i : flag of highest band */
296 : )
297 : {
298 : const Word16 *pt_fx;
299 : Word16 j;
300 :
301 10 : pt_fx = exc_diff_fx;
302 30 : FOR( j = 0; j < 2; j++ )
303 : {
304 20 : y_gain4_fx[j] = Comp_band_log_ener( pt_fx, 8, Q_exc, 1 ); /*Q12*/
305 20 : move16();
306 20 : pt_fx += 8;
307 : }
308 :
309 140 : FOR( j = 1; j < Mband - 2; j++ )
310 : {
311 130 : y_gain4_fx[j + 1] = Comp_band_log_ener( pt_fx, 16, Q_exc, 0 ); /*Q12*/
312 130 : move16();
313 130 : pt_fx += 16;
314 : }
315 :
316 10 : IF( EQ_16( Eflag, 1 ) )
317 : {
318 10 : y_gain4_fx[j + 1] = Comp_band_log_ener( pt_fx, 32, Q_exc, -1 ); /*Q12*/
319 10 : move16();
320 10 : pt_fx += 32;
321 : }
322 :
323 10 : return;
324 : }
325 :
326 207345 : void Ener_per_band_comp_ivas_fx(
327 : const Word16 exc_diff_fx[], /* i : target signal Q_exc_diff */
328 : Word16 y_gain4_fx[], /* o : Energy per band to quantize Q12 */
329 : const Word16 Q_exc, /* i : frame length */
330 : const Word16 Mband, /* i : Max band */
331 : const Word16 Eflag, /* i : flag of highest band */
332 : const Word16 L_frame /* i : frame length */
333 : )
334 : {
335 : const Word16 *pt_fx;
336 : Word16 j;
337 :
338 207345 : pt_fx = exc_diff_fx;
339 622035 : FOR( j = 0; j < 2; j++ )
340 : {
341 414690 : y_gain4_fx[j] = Comp_band_log_ener( pt_fx, 8, Q_exc, 1 ); /*Q12*/
342 414690 : move16();
343 414690 : pt_fx += 8;
344 : }
345 :
346 2902752 : FOR( j = 1; j < Mband - 2; j++ )
347 : {
348 2695407 : y_gain4_fx[j + 1] = Comp_band_log_ener( pt_fx, 16, Q_exc, 0 ); /*Q12*/
349 2695407 : move16();
350 2695407 : pt_fx += 16;
351 : }
352 :
353 207345 : IF( EQ_16( Eflag, 1 ) )
354 : {
355 207283 : y_gain4_fx[j + 1] = Comp_band_log_ener( pt_fx, 32, Q_exc, -1 ); /*Q12*/
356 207283 : move16();
357 207283 : pt_fx += 32;
358 : }
359 :
360 207345 : IF( EQ_16( L_frame, L_FRAME16k ) )
361 : {
362 75137 : y_gain4_fx[j + 2] = Comp_band_log_ener( pt_fx, 32, Q_exc, -1 ); /*Q12*/
363 75137 : move16();
364 75137 : y_gain4_fx[j + 3] = Comp_band_log_ener( pt_fx, 64, Q_exc, -1 ); /*Q12*/
365 75137 : move16();
366 75137 : pt_fx += 64;
367 : }
368 :
369 207345 : return;
370 : }
371 :
372 :
373 : /*-------------------------------------------------------------------*
374 : * gsc_gainQ()
375 : *
376 : * Quantization of the energy per band
377 : *-------------------------------------------------------------------*/
378 :
379 11 : static void GSC_gain_adj(
380 : const Word16 coder_type, /* i : Coder type */
381 : const Word32 core_brate, /* i : Bit rate */
382 : const Word16 mean_g, /* i : Average gain Q12 */
383 : Word16 *old_y_gain, /* i/o: Previous frame dequantized vector */
384 : const Word16 *y_gain_tmp, /* i : Dequantized gains */
385 : Word16 *y_gainQ /* i/o: Output gains Q12 */
386 : )
387 : {
388 : /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
389 : Word16 Gain_off, i;
390 :
391 11 : IF( coder_type != INACTIVE )
392 : {
393 0 : FOR( i = 0; i < MBANDS_GN; i++ )
394 : {
395 0 : old_y_gain[i] = y_gain_tmp[i];
396 0 : move16();
397 0 : y_gainQ[i] = add( y_gain_tmp[i], mean_g );
398 0 : move16();
399 : }
400 : }
401 : ELSE
402 : {
403 11 : Gain_off = 0;
404 11 : move16();
405 11 : IF( LE_32( core_brate, ACELP_7k20 ) )
406 : {
407 0 : Gain_off = 32767;
408 0 : move16(); /* 8 -> Q12 */
409 : }
410 11 : ELSE IF( LE_32( core_brate, ACELP_8k00 ) )
411 : {
412 0 : Gain_off = 27034;
413 0 : move16(); /* 6.6f -> Q12 */
414 : }
415 11 : ELSE IF( LE_32( core_brate, ACELP_9k60 ) )
416 : {
417 0 : Gain_off = 19661;
418 0 : move16(); /*4.8f-> Q12 */
419 : }
420 11 : ELSE IF( LE_32( core_brate, ACELP_11k60 ) )
421 : {
422 11 : Gain_off = 14336;
423 11 : move16(); /* 3.5f -> Q12 */
424 : }
425 0 : ELSE IF( LE_32( core_brate, ACELP_13k20 ) )
426 : {
427 0 : Gain_off = 12288;
428 0 : move16(); /* 3.0f -> Q12 dB */
429 : }
430 :
431 : /*mimic ACELP decay of energy for low rates*/
432 187 : FOR( i = 0; i < MBANDS_GN; i++ )
433 : {
434 176 : old_y_gain[i] = y_gain_tmp[i];
435 176 : move16();
436 : /*y_gainQ[i] = y_gain_tmp[i]+mean_4g[0]-(i*(Gain_off/20.f)/((float) Mbands_gn));*/
437 176 : y_gainQ[i] = add( y_gain_tmp[i], sub( mean_g, i_mult2( i, mult_r( Gain_off, 102 /* 20/MBANDS_GN in Q15 */ ) ) ) );
438 176 : move16();
439 : }
440 : }
441 :
442 11 : return;
443 : }
444 :
445 :
446 : /*-------------------------------------------------------------------*
447 : * GSC_gain_adj_ivas_fx()
448 : *
449 : * Quantization of the energy per band
450 : *-------------------------------------------------------------------*/
451 :
452 20554 : static void GSC_gain_adj_ivas_fx(
453 : const Word16 coder_type, /* i : Coder type */
454 : const Word16 Mbands_gn, /* i : Number of band */
455 : const Word32 core_brate, /* i : Bit rate */
456 : const Word16 mean_g, /* i : Average gain Q12 */
457 : Word16 *old_y_gain, /* i/o: Previous frame dequantized vector */
458 : const Word16 *y_gain_tmp, /* i : Dequantized gains */
459 : Word16 *y_gainQ /* i/o: Output gains Q12 */
460 : )
461 : {
462 : /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
463 : Word16 Gain_off, i;
464 :
465 20554 : test();
466 20554 : IF( ( coder_type != INACTIVE ) && NE_16( coder_type, UNVOICED ) )
467 : {
468 166141 : FOR( i = 0; i < Mbands_gn; i++ )
469 : {
470 156368 : old_y_gain[i] = y_gain_tmp[i];
471 156368 : move16();
472 156368 : y_gainQ[i] = add( y_gain_tmp[i], mean_g );
473 156368 : move16();
474 : }
475 : }
476 : ELSE
477 : {
478 10781 : Gain_off = 0;
479 10781 : move16();
480 :
481 10781 : test();
482 10781 : IF( LE_32( core_brate, ACELP_5k00 ) && EQ_16( coder_type, UNVOICED ) )
483 : {
484 8 : Gain_off = 18432;
485 8 : move16(); /* 9 -> Q11 */
486 : }
487 10781 : IF( LE_32( core_brate, ACELP_7k20 ) )
488 : {
489 6719 : Gain_off = 16384;
490 6719 : move16(); /* 8 -> Q11 */
491 : }
492 4062 : ELSE IF( LE_32( core_brate, ACELP_8k00 ) )
493 : {
494 13 : Gain_off = 13517;
495 13 : move16(); /* 6.6f -> Q11 */
496 : }
497 4049 : ELSE IF( LE_32( core_brate, ACELP_9k60 ) )
498 : {
499 354 : Gain_off = 9830;
500 354 : move16(); /*4.8f-> Q11 */
501 : }
502 3695 : ELSE IF( LE_32( core_brate, ACELP_11k60 ) )
503 : {
504 154 : Gain_off = 7168;
505 154 : move16(); /* 3.5f -> Q11 */
506 : }
507 3541 : ELSE IF( LE_32( core_brate, ACELP_13k20 ) )
508 : {
509 380 : Gain_off = 6144;
510 380 : move16(); /* 3.0f -> Q11 dB */
511 : }
512 :
513 : /*mimic ACELP decay of energy for low rates*/
514 188327 : FOR( i = 0; i < Mbands_gn; i++ )
515 : {
516 177546 : old_y_gain[i] = y_gain_tmp[i];
517 177546 : move16();
518 177546 : y_gainQ[i] = add( y_gain_tmp[i], sub( mean_g, i_mult2( i, mult_r( Gain_off, 205 /* 20/MBANDS_GN in Q16 */ ) ) ) );
519 177546 : move16();
520 : }
521 : }
522 :
523 20554 : return;
524 : }
525 :
526 :
527 : /*-------------------------------------------------------------------*
528 : * GSC_gain_DQ()
529 : *
530 : * Form the final vector after gain quantization/Dequantization
531 : * Common to both encoder and decoder
532 : *-------------------------------------------------------------------*/
533 :
534 22672 : static void GSC_gain_DQ_fx(
535 : const Word16 element_mode, /* i : element mode */
536 : const Word16 enc_dec, /* i : encoder/decoder flag */
537 : const Word16 coder_type, /* i : Coder type */
538 : const Word16 Mbands_gn, /* i : Number of band */
539 : const Word32 core_brate, /* i : Core bitrate */
540 : const Word16 mean_g, /* i : Average gain Q12 */
541 : const Word16 *Gain_in, /* i : Unquantized gain vector Q12 */
542 : Word16 *Gain_out /* o : Level adjusted unquantized gain vector Q12 */
543 : )
544 : {
545 : Word16 Gain_off;
546 : Word16 i;
547 :
548 : /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
549 22672 : Gain_off = 0;
550 22672 : move16();
551 :
552 22672 : test();
553 22672 : IF( coder_type == INACTIVE || EQ_16( coder_type, UNVOICED ) )
554 : {
555 11737 : test();
556 11737 : IF( LE_32( core_brate, ACELP_5k00 ) && EQ_16( coder_type, UNVOICED ) )
557 : {
558 0 : Gain_off = 1843; // 9/20 in Q12
559 0 : move16();
560 : }
561 11737 : ELSE IF( LE_32( core_brate, ACELP_7k20 ) )
562 : {
563 7531 : Gain_off = 1638; // 8/20 in Q12; /* 0 dB */
564 7531 : move16();
565 : }
566 4206 : ELSE IF( LE_32( core_brate, ACELP_8k00 ) )
567 : {
568 11 : Gain_off = 1351; // 6.6f/20 in Q12 /* ~-3.3 dB */
569 11 : move16();
570 : }
571 4195 : ELSE IF( LE_32( core_brate, ACELP_9k60 ) )
572 : {
573 339 : Gain_off = 983; // 4.8f/20 in Q12 /* ~-2.4 dB */
574 339 : move16();
575 : }
576 3856 : ELSE IF( LE_32( core_brate, ACELP_11k60 ) )
577 : {
578 173 : Gain_off = 717; // 3.5f/20 in Q12 /* ~-2.4 dB */
579 173 : move16();
580 : }
581 3683 : ELSE IF( LE_32( core_brate, ACELP_13k20 ) )
582 : {
583 386 : Gain_off = 614; // 3.0f/20 in Q12 /* ~-2.4 dB */
584 386 : move16();
585 : }
586 : }
587 :
588 22672 : test();
589 22672 : IF( coder_type != INACTIVE && NE_16( coder_type, UNVOICED ) )
590 : {
591 185895 : FOR( i = 0; i < Mbands_gn; i++ )
592 : {
593 174960 : Gain_out[i] = add( Gain_in[i], mean_g ); // Q12
594 174960 : move16();
595 : }
596 : }
597 : ELSE
598 : {
599 : /*mimic ACELP decay of energy for low rates*/
600 11737 : test();
601 11737 : IF( element_mode == EVS_MONO && EQ_16( enc_dec, DEC ) )
602 : {
603 : /* This is to keep EVS mono bit-exact with the standard (there might be a small desynchronization between encoder and decoder but there is no real quality or interop. issue) */
604 0 : FOR( i = 0; i < Mbands_gn; i++ )
605 : {
606 0 : Gain_out[i] = add( Gain_out[i], sub( mean_g, mult( Gain_off, div_s( i, Mbands_gn ) ) ) ); // Q12
607 0 : move16();
608 : // Gain_out[i] += mean_g - i * ( Gain_off / 20.f ) / ( (float) Mbands_gn );
609 : }
610 : }
611 : ELSE
612 : {
613 204847 : FOR( i = 0; i < Mbands_gn; i++ )
614 : {
615 193110 : Gain_out[i] = add( Gain_in[i], sub( mean_g, mult( Gain_off, div_s( i, Mbands_gn ) ) ) ); // Q12
616 193110 : move16();
617 : // Gain_out[i] = Gain_in[i] + mean_g - ( i * ( Gain_off / 20.f ) / ( (float) Mbands_gn ) );
618 : }
619 : }
620 : }
621 :
622 22672 : return;
623 : }
624 :
625 :
626 : /*-------------------------------------------------------------------*
627 : * gsc_gainQ()
628 : *
629 : * Quantization of the energy per band
630 : *-------------------------------------------------------------------*/
631 :
632 22672 : Word16 gsc_gainQ_ivas_fx(
633 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
634 : const Word16 element_mode, /* i : element mode */
635 : const Word16 idchan, /* i : channel ID */
636 : const Word16 y_gain4[],
637 : /* i : Energy per band */ // Q12
638 : Word16 y_gainQ[],
639 : /* o : quantized energy per band */ // Q12
640 : const Word32 core_brate, /* i : Core rate */
641 : const Word16 coder_type, /* i : coding type */
642 : const Word16 bwidth, /* i : input signal bandwidth */
643 : const Word16 L_frame, /* i : frame length */
644 : const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */
645 : const Word32 core_brate_inp /* i : true core bitrate */
646 : )
647 : {
648 : Word16 y_gain_tmp[MBANDS_GN16k];
649 : Word16 y_gain_tmp2[MBANDS_GN16k];
650 22672 : Word16 i, idx_g = 0;
651 22672 : move16();
652 : Word16 mean_4g_fx[1], ftmp1_fx;
653 22672 : Word16 Mbands_gn = MBANDS_GN;
654 22672 : move16();
655 : Word16 y_gain_tmp3[MBANDS_GN];
656 : Word32 L_tmp;
657 :
658 22672 : if ( EQ_16( L_frame, L_FRAME16k ) )
659 : {
660 2659 : Mbands_gn = MBANDS_GN16k;
661 2659 : move16();
662 : }
663 :
664 22672 : mean_4g_fx[0] = 0;
665 22672 : move32();
666 :
667 22672 : test();
668 22672 : test();
669 22672 : IF( ( EQ_16( coder_type, AUDIO ) || coder_type == INACTIVE ) && bwidth == NB )
670 : {
671 0 : L_tmp = 0;
672 0 : move32();
673 0 : FOR( i = 0; i < 10; i++ )
674 : {
675 0 : L_tmp = L_add( L_tmp, y_gain4[i] );
676 : }
677 0 : L_tmp = L_sub( Mpy_32_16_1( L_tmp, 3277 /* (1/10.0f) in Q15 */ ), 2457 /* 0.6f in Q12 */ ); // Q12
678 0 : ftmp1_fx = extract_l( L_tmp );
679 0 : FOR( i = 0; i < Mbands_gn; i++ )
680 : {
681 0 : IF( LT_16( y_gain4[i], ftmp1_fx ) )
682 : {
683 0 : y_gain_tmp2[i] = ftmp1_fx; /*Q12*/
684 : }
685 : ELSE
686 : {
687 0 : y_gain_tmp2[i] = y_gain4[i]; /*Q12*/
688 : }
689 0 : move16();
690 : }
691 :
692 : /* Quantized mean gain without clipping */
693 0 : L_tmp = 0;
694 0 : move32();
695 0 : FOR( i = 0; i < 10; i++ )
696 : {
697 0 : L_tmp = L_add( L_tmp, y_gain4[i] );
698 : }
699 0 : L_tmp = Mpy_32_16_1( L_tmp, 3277 /* (1/10.0f) in Q15 */ ); // Q12
700 0 : mean_4g_fx[0] = extract_l( L_tmp ); // Q12
701 0 : move16();
702 0 : idx_g = vquant_fx( mean_4g_fx, Gain_meanNB_fx, mean_4g_fx, Gain_mean_dicNB_fx, 1, 64 );
703 0 : push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
704 :
705 0 : FOR( i = 0; i < Mbands_gn; i++ )
706 : {
707 0 : y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g_fx[0] ); // Q12
708 0 : move16();
709 : }
710 :
711 0 : if ( LT_16( y_gain_tmp[9], -1229 /* -0.3f in Q12 */ ) )
712 : {
713 0 : y_gain_tmp[9] = -1229; /* -0.3f in Q12 */
714 0 : move16();
715 : }
716 :
717 0 : set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
718 0 : idx_g = vquant_fx( y_gain_tmp, Mean_dic_NB_fx, y_gain_tmp, Gain_dic1_NB_fx, 3, 64 );
719 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
720 :
721 0 : IF( LT_32( core_brate, ACELP_9k60 ) )
722 : {
723 0 : idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NB_fx, 3, 32 );
724 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
725 :
726 0 : idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NB_fx, 4, 16 );
727 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
728 : }
729 : ELSE
730 : {
731 0 : idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NBHR_fx, 3, 64 );
732 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
733 :
734 0 : idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NBHR_fx, 4, 128 );
735 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 );
736 : }
737 :
738 0 : test();
739 0 : IF( LE_32( core_brate, ACELP_9k60 ) && coder_type == INACTIVE )
740 : {
741 : /* Some energy is needed in high band for stat_noise_uv_enc() to be functional in inactive speech */
742 0 : y_gain_tmp[10] = mean_fx( y_gain_tmp + 6, 3 ); /*Q12*/
743 0 : move16();
744 0 : y_gain_tmp[11] = mean_fx( y_gain_tmp + 7, 3 ); /*Q12*/
745 0 : move16();
746 0 : y_gain_tmp[12] = mean_fx( y_gain_tmp + 8, 3 ); /*Q12*/
747 0 : move16();
748 0 : y_gain_tmp[13] = mean_fx( y_gain_tmp + 9, 3 ); /*Q12*/
749 0 : move16();
750 0 : y_gain_tmp[14] = mean_fx( y_gain_tmp + 10, 3 ); /*Q12*/
751 0 : move16();
752 0 : y_gain_tmp[15] = mean_fx( y_gain_tmp + 11, 3 ); /*Q12*/
753 0 : move16();
754 : }
755 : ELSE
756 : {
757 0 : set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
758 : }
759 : }
760 : ELSE
761 : {
762 22672 : L_tmp = 0;
763 22672 : move32();
764 385424 : FOR( i = 0; i < 16; i++ )
765 : {
766 362752 : L_tmp = L_add( L_tmp, y_gain4[i] );
767 : }
768 22672 : L_tmp = Mpy_32_16_1( L_tmp, 2048 /* (1/16.f) in Q15 */ ); // Q12
769 22672 : ftmp1_fx = extract_l( L_tmp );
770 390742 : FOR( i = 0; i < Mbands_gn; i++ )
771 : {
772 368070 : IF( LT_16( y_gain4[i], sub( ftmp1_fx, 2457 /* 0.6 in Q12*/ ) ) )
773 : {
774 1945 : y_gain_tmp2[i] = sub( ftmp1_fx, 2457 /* 0.6 in Q12*/ );
775 : }
776 366125 : ELSE IF( GT_16( y_gain4[i], add( ftmp1_fx, 2457 /* 0.6 in Q12*/ ) ) )
777 : {
778 536 : y_gain_tmp2[i] = add( ftmp1_fx, 2457 /* 0.6 in Q12*/ );
779 : }
780 : ELSE
781 : {
782 365589 : y_gain_tmp2[i] = y_gain4[i];
783 : }
784 368070 : move16();
785 : }
786 :
787 22672 : L_tmp = 0;
788 22672 : move32();
789 385424 : FOR( i = 0; i < 16; i++ )
790 : {
791 362752 : L_tmp = L_add( L_tmp, y_gain_tmp2[i] );
792 : }
793 22672 : L_tmp = Mpy_32_16_1( L_tmp, 2048 /* (1/16.f) in Q15 */ ); // Q12
794 22672 : mean_4g_fx[0] = extract_l( L_tmp ); // Q12
795 22672 : move16();
796 22672 : idx_g = vquant_fx( mean_4g_fx, mean_m_fx, mean_4g_fx, mean_gain_dic_fx, 1, 64 );
797 22672 : push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
798 :
799 : /* Subtraction of the average gain */
800 390742 : FOR( i = 0; i < Mbands_gn; i++ )
801 : {
802 368070 : y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g_fx[0] ); // Q12
803 368070 : move16();
804 : }
805 :
806 22672 : IF( LT_32( core_brate, ACELP_9k60 ) )
807 : {
808 : /* prediction and quantization of the average gain */
809 :
810 : /*--------------------------------------------------------------------------------------*
811 : * Quantization of the first 8 bands
812 : * Keep only 4 bands out of the last 8 bands
813 : *--------------------------------------------------------------------------------------*/
814 :
815 14517 : Copy( y_gain_tmp, y_gain_tmp2, 8 );
816 :
817 14517 : y_gain_tmp2[8] = y_gain_tmp[8];
818 14517 : move16();
819 14517 : y_gain_tmp2[9] = y_gain_tmp[10];
820 14517 : move16();
821 14517 : y_gain_tmp2[10] = y_gain_tmp[12];
822 14517 : move16();
823 14517 : y_gain_tmp2[11] = y_gain_tmp[14];
824 14517 : move16();
825 :
826 14517 : idx_g = 0;
827 14517 : move16();
828 14517 : idx_g = vquant_fx( y_gain_tmp2, YGain_mean_LR_fx, y_gain_tmp2, YGain_dic1_LR_fx, 3, 32 );
829 14517 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
830 :
831 14517 : test();
832 14517 : test();
833 14517 : test();
834 14517 : IF( !( coder_type == INACTIVE && tdm_LRTD_flag == 0 && EQ_16( idchan, 1 ) ) || GT_32( core_brate_inp, GSC_LRES_GAINQ_LIMIT ) )
835 : {
836 14517 : idx_g = vquant_fx( y_gain_tmp2 + 3, YGain_mean_LR_fx + 3, y_gain_tmp2 + 3, YGain_dic2_LR_fx, 4, 32 );
837 14517 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
838 :
839 : /*----------------------------------------------------------------------*
840 : * Vector quantization of the first 8 bands + quantization of the 4 bands out of the last 8
841 : * Interpolation of the last 4 bands Q to create bands 8-16
842 : *----------------------------------------------------------------------*/
843 :
844 14517 : idx_g = vquant_fx( y_gain_tmp2 + 7, YGain_mean_LR_fx + 7, y_gain_tmp2 + 7, YGain_dic3_LR_fx, 5, 32 );
845 14517 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
846 :
847 14517 : set16_fx( y_gain_tmp2 + 12, 0, MBANDS_GN - 12 );
848 :
849 : /* Update to quantized vector */
850 14517 : Copy( y_gain_tmp2, y_gain_tmp, 8 );
851 :
852 14517 : Copy( y_gain_tmp2 + 8, y_gain_tmp3, 4 );
853 14517 : set16_fx( y_gain_tmp + 8, 0, 8 );
854 14517 : fft_rel_fx( y_gain_tmp2 + 8, 4, 2 );
855 :
856 14517 : Copy( y_gain_tmp2 + 8, y_gain_tmp + 8, 3 );
857 14517 : y_gain_tmp[15] = y_gain_tmp2[11];
858 14517 : move16();
859 14517 : ifft_rel_fx( y_gain_tmp + 8, 8, 3 );
860 :
861 130653 : FOR( i = 8; i < 16; i++ )
862 : {
863 116136 : y_gain_tmp[i] = shl( mult( y_gain_tmp[i], 23101 /* 1.41 in Q14 */ ), 1 ); /*Q12*/
864 116136 : move16();
865 : }
866 :
867 14517 : y_gain_tmp[8] = y_gain_tmp3[0];
868 14517 : move16();
869 14517 : y_gain_tmp[10] = y_gain_tmp3[1];
870 14517 : move16();
871 14517 : y_gain_tmp[12] = y_gain_tmp3[2];
872 14517 : move16();
873 14517 : y_gain_tmp[14] = y_gain_tmp3[3];
874 14517 : move16();
875 : }
876 : ELSE
877 : {
878 0 : Copy( y_gain_tmp2, y_gain_tmp, 3 );
879 0 : set16_fx( y_gain_tmp + 3, 0, MBANDS_GN16k - 3 );
880 : }
881 : }
882 : ELSE
883 : {
884 8155 : IF( EQ_16( L_frame, L_FRAME ) )
885 : {
886 5496 : idx_g = vquant_fx( y_gain_tmp, YG_mean16_fx, y_gain_tmp, YG_dicMR_1_fx, 4, 64 );
887 5496 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
888 :
889 5496 : idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16_fx + 4, y_gain_tmp + 4, YG_dicMR_2_fx, 4, 32 );
890 5496 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
891 :
892 5496 : idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16_fx + 8, y_gain_tmp + 8, YG_dicMR_3_fx, 4, 32 );
893 5496 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
894 :
895 5496 : idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16_fx + 12, y_gain_tmp + 12, YG_dicMR_4_fx, 4, 16 );
896 5496 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
897 : }
898 : ELSE
899 : {
900 2659 : idx_g = vquant_fx( y_gain_tmp, YG_mean16HR_fx, y_gain_tmp, YG_dicHR_1_fx, 4, 128 );
901 2659 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 );
902 :
903 2659 : idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16HR_fx + 4, y_gain_tmp + 4, YG_dicHR_2_fx, 4, 64 );
904 2659 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
905 :
906 2659 : idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16HR_fx + 8, y_gain_tmp + 8, YG_dicHR_3_fx, 4, 64 );
907 2659 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
908 :
909 2659 : idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16HR_16kHz_fx, y_gain_tmp + 12, YG_dicHR_4_16kHz_fx, 4, 64 );
910 2659 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
911 :
912 2659 : idx_g = vquant_fx( y_gain_tmp + 16, YG_meanL2G_16kHz_fx, y_gain_tmp + 16, YG_dicL2G_16kHz_fx, 2, 8 );
913 2659 : push_indice( hBstr, IND_Y_GAIN_HF, idx_g, 3 );
914 : }
915 : }
916 : }
917 :
918 22672 : GSC_gain_DQ_fx( element_mode, ENC, coder_type, Mbands_gn, core_brate, mean_4g_fx[0], y_gain_tmp, y_gainQ );
919 :
920 22672 : return mean_4g_fx[0];
921 : }
922 :
923 :
924 : /*==========================================================================*/
925 : /* FUNCTION : Word16 gsc_gaindec_fx () */
926 : /*--------------------------------------------------------------------------*/
927 : /* PURPOSE : Generic signal frequency band decoding and application */
928 : /*--------------------------------------------------------------------------*/
929 : /* INPUT ARGUMENTS : */
930 : /* _ (Word16) pvq_bits_fx : core used Q0 */
931 : /* _ (Word16) coder_type : coding type Q0 */
932 : /* _ (Word16) core_fx : core used Q0 */
933 : /* _ (Word16) bwidth_fx : input signal bandwidth Q0 */
934 : /*--------------------------------------------------------------------------*/
935 : /* OUTPUT ARGUMENTS : */
936 : /* _ (Word16[]) y_gainQ_fx : quantized gain per band */
937 : /*--------------------------------------------------------------------------*/
938 : /* INPUT/OUTPUT ARGUMENTS : */
939 : /* _ (Word16[]) old_y_gain_fx : AR gain quantizer for low rate */
940 : /*--------------------------------------------------------------------------*/
941 : /* RETURN ARGUMENTS : */
942 : /* _ (Word16) : average frequency gain */
943 : /*==========================================================================*/
944 :
945 6 : Word16 gsc_gaindec_fx( /* o : average frequency gain */
946 : Decoder_State *st_fx, /* i/o: decoder state structure */
947 : Word16 y_gainQ_fx[], /* o : quantized gain per band */
948 : const Word32 core_brate_fx, /* i : core used */
949 : Word16 old_y_gain_fx[], /* i/o: AR gain quantizer for low rate */
950 : const Word16 coder_type, /* i : coding type */
951 : const Word16 bwidth_fx /* i : input signal bandwidth */
952 : )
953 : {
954 : Word16 idx_g_fx, i;
955 : Word16 mean_4g_fx;
956 : Word16 y_gain_tmp3_fx[MBANDS_GN];
957 :
958 6 : test();
959 6 : test();
960 6 : IF( ( EQ_16( coder_type, AUDIO ) || ( coder_type == INACTIVE ) ) && EQ_16( bwidth_fx, NB ) )
961 : {
962 0 : idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 6 ) );
963 0 : VDQ_vec_fx( &mean_4g_fx, Gain_meanNB_fx, Gain_mean_dicNB_fx, idx_g_fx, 1 );
964 :
965 0 : idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 6 ) );
966 0 : VDQ_vec_fx( y_gainQ_fx, Mean_dic_NB_fx, Gain_dic1_NB_fx, idx_g_fx, 3 );
967 :
968 0 : IF( LT_32( core_brate_fx, ACELP_9k60 ) )
969 : {
970 0 : idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 5 ) );
971 0 : VDQ_vec_fx( y_gainQ_fx + 3, Mean_dic_NB_fx + 3, Gain_dic2_NB_fx, idx_g_fx, 3 );
972 :
973 0 : idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 4 ) );
974 0 : VDQ_vec_fx( y_gainQ_fx + 6, Mean_dic_NB_fx + 6, Gain_dic3_NB_fx, idx_g_fx, 4 );
975 : }
976 : ELSE
977 : {
978 0 : idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 6 ) );
979 0 : VDQ_vec_fx( y_gainQ_fx + 3, Mean_dic_NB_fx + 3, Gain_dic2_NBHR_fx, idx_g_fx, 3 );
980 :
981 0 : idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 7 ) );
982 0 : VDQ_vec_fx( y_gainQ_fx + 6, Mean_dic_NB_fx + 6, Gain_dic3_NBHR_fx, idx_g_fx, 4 );
983 : }
984 0 : test();
985 0 : IF( LE_32( core_brate_fx, ACELP_9k60 ) && ( coder_type == INACTIVE ) )
986 : {
987 : /* Some energy is needed in high band for stat_noise_uv_enc
988 : to be functional in inactive speech */
989 0 : y_gainQ_fx[10] = mean_fx( y_gainQ_fx + 6, 3 );
990 0 : move16();
991 0 : y_gainQ_fx[11] = mean_fx( y_gainQ_fx + 7, 3 );
992 0 : move16();
993 0 : y_gainQ_fx[12] = mean_fx( y_gainQ_fx + 8, 3 );
994 0 : move16();
995 0 : y_gainQ_fx[13] = mean_fx( y_gainQ_fx + 9, 3 );
996 0 : move16();
997 0 : y_gainQ_fx[14] = mean_fx( y_gainQ_fx + 10, 3 );
998 0 : move16();
999 0 : y_gainQ_fx[15] = mean_fx( y_gainQ_fx + 11, 3 );
1000 0 : move16();
1001 : }
1002 : ELSE
1003 : {
1004 0 : set16_fx( y_gainQ_fx + 10, 0, MBANDS_GN - 10 );
1005 : }
1006 : }
1007 : ELSE
1008 : {
1009 6 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1010 :
1011 6 : VDQ_vec_fx( &mean_4g_fx, mean_m_fx, mean_gain_dic_fx, idx_g_fx, 1 );
1012 :
1013 6 : IF( LE_32( core_brate_fx, ACELP_9k60 ) )
1014 : {
1015 : /*--------------------------------------------------------------------------------------*
1016 : * UQ of the first 8 bands and half of the last 8 bands
1017 : *--------------------------------------------------------------------------------------*/
1018 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1019 0 : VDQ_vec_fx( y_gainQ_fx, YGain_mean_LR_fx, YGain_dic1_LR_fx, idx_g_fx, 3 );
1020 :
1021 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1022 0 : VDQ_vec_fx( y_gainQ_fx + 3, YGain_mean_LR_fx + 3, YGain_dic2_LR_fx, idx_g_fx, 4 );
1023 :
1024 : /*----------------------------------------------------------------------*
1025 : * Interpolation of the last 4 Q bands to create bands 8-16
1026 : * And scaling
1027 : *----------------------------------------------------------------------*/
1028 :
1029 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1030 :
1031 0 : VDQ_vec_fx( y_gainQ_fx + 7, YGain_mean_LR_fx + 7, YGain_dic3_LR_fx, idx_g_fx, 5 );
1032 :
1033 0 : Copy( y_gainQ_fx + 8, y_gain_tmp3_fx, 4 );
1034 0 : set16_fx( y_gainQ_fx + 12, 0, 4 );
1035 :
1036 0 : fft_rel_fx( y_gainQ_fx + 8, 4, 2 );
1037 :
1038 0 : y_gainQ_fx[15] = y_gainQ_fx[11];
1039 0 : move16();
1040 0 : y_gainQ_fx[11] = 0;
1041 0 : move16();
1042 0 : ifft_rel_fx( y_gainQ_fx + 8, 8, 3 );
1043 0 : FOR( i = 8; i < 16; i++ )
1044 : {
1045 0 : y_gainQ_fx[i] = round_fx( L_shl( L_mult( y_gainQ_fx[i], 23101 ), 1 ) ); /*Q12 */
1046 0 : move16();
1047 : }
1048 : /*----------------------------------------------------------------------*
1049 : * Copy the true Q values in the specific bands
1050 : *----------------------------------------------------------------------*/
1051 0 : y_gainQ_fx[8] = y_gain_tmp3_fx[0];
1052 0 : move16();
1053 0 : y_gainQ_fx[10] = y_gain_tmp3_fx[1];
1054 0 : move16();
1055 0 : y_gainQ_fx[12] = y_gain_tmp3_fx[2];
1056 0 : move16();
1057 0 : y_gainQ_fx[14] = y_gain_tmp3_fx[3];
1058 0 : move16();
1059 : }
1060 : ELSE
1061 : {
1062 6 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1063 6 : VDQ_vec_fx( y_gainQ_fx, YG_mean16_fx, YG_dicMR_1_fx, idx_g_fx, 4 );
1064 :
1065 6 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1066 6 : VDQ_vec_fx( y_gainQ_fx + 4, YG_mean16_fx + 4, YG_dicMR_2_fx, idx_g_fx, 4 );
1067 :
1068 6 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1069 6 : VDQ_vec_fx( y_gainQ_fx + 8, YG_mean16_fx + 8, YG_dicMR_3_fx, idx_g_fx, 4 );
1070 :
1071 6 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 4 );
1072 6 : VDQ_vec_fx( y_gainQ_fx + 12, YG_mean16_fx + 12, YG_dicMR_4_fx, idx_g_fx, 4 );
1073 : }
1074 : }
1075 :
1076 : /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
1077 6 : GSC_gain_adj( coder_type, core_brate_fx, mean_4g_fx, old_y_gain_fx, y_gainQ_fx, y_gainQ_fx );
1078 :
1079 6 : return mean_4g_fx;
1080 : }
1081 :
1082 :
1083 : /*==========================================================================*/
1084 : /* FUNCTION : Word16 gsc_gaindec_ivas_fx () */
1085 : /*--------------------------------------------------------------------------*/
1086 : /* PURPOSE : Generic signal frequency band decoding and application */
1087 : /*--------------------------------------------------------------------------*/
1088 : /* INPUT ARGUMENTS : */
1089 : /* _ (Word16) pvq_bits_fx : core used Q0 */
1090 : /* _ (Word16) coder_type : coding type Q0 */
1091 : /* _ (Word16) core_fx : core used Q0 */
1092 : /* _ (Word16) bwidth_fx : input signal bandwidth Q0 */
1093 : /*--------------------------------------------------------------------------*/
1094 : /* OUTPUT ARGUMENTS : */
1095 : /* _ (Word16[]) y_gainQ_fx : quantized gain per band */
1096 : /*--------------------------------------------------------------------------*/
1097 : /* INPUT/OUTPUT ARGUMENTS : */
1098 : /* _ (Word16[]) old_y_gain_fx : AR gain quantizer for low rate */
1099 : /*--------------------------------------------------------------------------*/
1100 : /* RETURN ARGUMENTS : */
1101 : /* _ (Word16) : average frequency gain */
1102 : /*==========================================================================*/
1103 :
1104 20554 : Word16 gsc_gaindec_ivas_fx( /* o : average frequency gain */
1105 : Decoder_State *st_fx, /* i/o: decoder state structure */
1106 : Word16 y_gainQ_fx[], /* o : quantized gain per band Q12 */
1107 : const Word32 core_brate_fx, /* i : core used */
1108 : Word16 old_y_gain_fx[], /* i/o: AR gain quantizer for low rate */
1109 : const Word16 coder_type, /* i : coding type */
1110 : const Word16 bwidth_fx /* i : input signal bandwidth */
1111 : )
1112 : {
1113 : Word16 idx_g_fx, i;
1114 : Word16 mean_4g_fx;
1115 20554 : Word16 Mbands_gn = MBANDS_GN;
1116 20554 : move16();
1117 : Word16 y_gain_tmp3_fx[MBANDS_GN];
1118 20554 : if ( EQ_16( st_fx->L_frame, L_FRAME16k ) )
1119 : {
1120 2525 : Mbands_gn = MBANDS_GN16k;
1121 2525 : move16();
1122 : }
1123 :
1124 20554 : test();
1125 20554 : test();
1126 20554 : IF( ( EQ_16( coder_type, AUDIO ) || ( coder_type == INACTIVE ) ) && EQ_16( bwidth_fx, NB ) )
1127 : {
1128 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1129 0 : VDQ_vec_fx( &mean_4g_fx, Gain_meanNB_fx, Gain_mean_dicNB_fx, idx_g_fx, 1 );
1130 :
1131 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1132 0 : VDQ_vec_fx( y_gainQ_fx, Mean_dic_NB_fx, Gain_dic1_NB_fx, idx_g_fx, 3 );
1133 :
1134 0 : IF( LT_32( core_brate_fx, ACELP_9k60 ) )
1135 : {
1136 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1137 0 : VDQ_vec_fx( y_gainQ_fx + 3, Mean_dic_NB_fx + 3, Gain_dic2_NB_fx, idx_g_fx, 3 );
1138 :
1139 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 4 );
1140 0 : VDQ_vec_fx( y_gainQ_fx + 6, Mean_dic_NB_fx + 6, Gain_dic3_NB_fx, idx_g_fx, 4 );
1141 : }
1142 : ELSE
1143 : {
1144 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1145 0 : VDQ_vec_fx( y_gainQ_fx + 3, Mean_dic_NB_fx + 3, Gain_dic2_NBHR_fx, idx_g_fx, 3 );
1146 :
1147 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 7 );
1148 0 : VDQ_vec_fx( y_gainQ_fx + 6, Mean_dic_NB_fx + 6, Gain_dic3_NBHR_fx, idx_g_fx, 4 );
1149 : }
1150 0 : test();
1151 0 : IF( LE_32( core_brate_fx, ACELP_9k60 ) && ( coder_type == INACTIVE ) )
1152 : {
1153 : /* Some energy is needed in high band for stat_noise_uv_enc
1154 : to be functional in inactive speech */
1155 0 : y_gainQ_fx[10] = mean_fx( y_gainQ_fx + 6, 3 ); /*Q12*/
1156 0 : move16();
1157 0 : y_gainQ_fx[11] = mean_fx( y_gainQ_fx + 7, 3 ); /*Q12*/
1158 0 : move16();
1159 0 : y_gainQ_fx[12] = mean_fx( y_gainQ_fx + 8, 3 ); /*Q12*/
1160 0 : move16();
1161 0 : y_gainQ_fx[13] = mean_fx( y_gainQ_fx + 9, 3 ); /*Q12*/
1162 0 : move16();
1163 0 : y_gainQ_fx[14] = mean_fx( y_gainQ_fx + 10, 3 ); /*Q12*/
1164 0 : move16();
1165 0 : y_gainQ_fx[15] = mean_fx( y_gainQ_fx + 11, 3 ); /*Q12*/
1166 0 : move16();
1167 : }
1168 : ELSE
1169 : {
1170 0 : set16_fx( y_gainQ_fx + 10, 0, MBANDS_GN - 10 );
1171 : }
1172 : }
1173 : ELSE
1174 : {
1175 20554 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1176 :
1177 20554 : VDQ_vec_fx( &mean_4g_fx, mean_m_fx, mean_gain_dic_fx, idx_g_fx, 1 );
1178 :
1179 20554 : IF( LT_32( core_brate_fx, ACELP_9k60 ) )
1180 : {
1181 : /*--------------------------------------------------------------------------------------*
1182 : * UQ of the first 8 bands and half of the last 8 bands
1183 : *--------------------------------------------------------------------------------------*/
1184 13136 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1185 13136 : VDQ_vec_fx( y_gainQ_fx, YGain_mean_LR_fx, YGain_dic1_LR_fx, idx_g_fx, 3 );
1186 :
1187 13136 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1188 13136 : VDQ_vec_fx( y_gainQ_fx + 3, YGain_mean_LR_fx + 3, YGain_dic2_LR_fx, idx_g_fx, 4 );
1189 :
1190 : /*----------------------------------------------------------------------*
1191 : * Interpolation of the last 4 Q bands to create bands 8-16
1192 : * And scaling
1193 : *----------------------------------------------------------------------*/
1194 :
1195 13136 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1196 :
1197 13136 : VDQ_vec_fx( y_gainQ_fx + 7, YGain_mean_LR_fx + 7, YGain_dic3_LR_fx, idx_g_fx, 5 );
1198 :
1199 13136 : Copy( y_gainQ_fx + 8, y_gain_tmp3_fx, 4 );
1200 13136 : set16_fx( y_gainQ_fx + 12, 0, 4 );
1201 :
1202 13136 : fft_rel_fx( y_gainQ_fx + 8, 4, 2 );
1203 :
1204 13136 : y_gainQ_fx[15] = y_gainQ_fx[11];
1205 13136 : move16();
1206 13136 : y_gainQ_fx[11] = 0;
1207 13136 : move16();
1208 13136 : ifft_rel_fx( y_gainQ_fx + 8, 8, 3 );
1209 118224 : FOR( i = 8; i < 16; i++ )
1210 : {
1211 105088 : y_gainQ_fx[i] = round_fx( L_shl( L_mult( y_gainQ_fx[i], 23101 ), 1 ) ); /*Q12 */
1212 105088 : move16();
1213 : }
1214 : /*----------------------------------------------------------------------*
1215 : * Copy the true Q values in the specific bands
1216 : *----------------------------------------------------------------------*/
1217 13136 : y_gainQ_fx[8] = y_gain_tmp3_fx[0]; /*Q12*/
1218 13136 : move16();
1219 13136 : y_gainQ_fx[10] = y_gain_tmp3_fx[1]; /*Q12*/
1220 13136 : move16();
1221 13136 : y_gainQ_fx[12] = y_gain_tmp3_fx[2]; /*Q12*/
1222 13136 : move16();
1223 13136 : y_gainQ_fx[14] = y_gain_tmp3_fx[3]; /*Q12*/
1224 13136 : move16();
1225 : }
1226 : ELSE
1227 : {
1228 7418 : IF( EQ_16( st_fx->L_frame, L_FRAME ) )
1229 : {
1230 4893 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1231 4893 : VDQ_vec_fx( y_gainQ_fx, YG_mean16_fx, YG_dicMR_1_fx, idx_g_fx, 4 );
1232 :
1233 4893 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1234 4893 : VDQ_vec_fx( y_gainQ_fx + 4, YG_mean16_fx + 4, YG_dicMR_2_fx, idx_g_fx, 4 );
1235 :
1236 4893 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1237 4893 : VDQ_vec_fx( y_gainQ_fx + 8, YG_mean16_fx + 8, YG_dicMR_3_fx, idx_g_fx, 4 );
1238 :
1239 4893 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 4 );
1240 4893 : VDQ_vec_fx( y_gainQ_fx + 12, YG_mean16_fx + 12, YG_dicMR_4_fx, idx_g_fx, 4 );
1241 : }
1242 : ELSE
1243 : {
1244 2525 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 7 );
1245 2525 : VDQ_vec_fx( y_gainQ_fx, YG_mean16HR_fx, YG_dicHR_1_fx, idx_g_fx, 4 );
1246 :
1247 2525 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1248 2525 : VDQ_vec_fx( y_gainQ_fx + 4, YG_mean16HR_fx + 4, YG_dicHR_2_fx, idx_g_fx, 4 );
1249 :
1250 2525 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1251 2525 : VDQ_vec_fx( y_gainQ_fx + 8, YG_mean16HR_fx + 8, YG_dicHR_3_fx, idx_g_fx, 4 );
1252 :
1253 2525 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1254 2525 : VDQ_vec_fx( y_gainQ_fx + 12, YG_mean16HR_16kHz_fx, YG_dicHR_4_16kHz_fx, idx_g_fx, 4 );
1255 :
1256 2525 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 3 );
1257 2525 : VDQ_vec_fx( y_gainQ_fx + 16, YG_meanL2G_16kHz_fx, YG_dicL2G_16kHz_fx, idx_g_fx, 2 );
1258 : }
1259 : }
1260 : }
1261 :
1262 : /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
1263 20554 : GSC_gain_adj_ivas_fx( coder_type, Mbands_gn, core_brate_fx, mean_4g_fx, old_y_gain_fx, y_gainQ_fx, y_gainQ_fx );
1264 :
1265 20554 : return mean_4g_fx;
1266 : }
1267 :
1268 :
1269 : /*-------------------------------------------------------------------*
1270 : * gsc_gainQ()
1271 : *
1272 : * Quantization of the energy per band
1273 : *-------------------------------------------------------------------*/
1274 :
1275 5 : Word16 gsc_gainQ_fx( /*Q12*/
1276 : BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */
1277 : const Word16 y_gain4[], /* i : Energy per band Q12 */
1278 : Word16 y_gainQ[], /* o : quantized energy per band Q12 */
1279 : const Word32 core_brate, /* i : Core rate */
1280 : const Word16 coder_type, /* i : coding type */
1281 : const Word16 bwidth /* i : input signal bandwidth */
1282 : )
1283 : {
1284 : Word16 y_gain_tmp[MBANDS_GN], y_gain_tmp2[MBANDS_GN];
1285 5 : Word16 i, idx_g = 0;
1286 5 : move16();
1287 5 : Word16 mean_4g[1] = { 0 }, tmp16, tmp1, tmp2;
1288 5 : move16();
1289 5 : Word16 Mbands_gn = MBANDS_GN;
1290 : Word16 y_gain_tmp3[MBANDS_GN];
1291 : Word16 cnt;
1292 : Word32 L_tmp;
1293 :
1294 5 : mean_4g[0] = 0;
1295 :
1296 5 : test();
1297 5 : test();
1298 5 : IF( ( EQ_16( coder_type, AUDIO ) || ( coder_type == INACTIVE ) ) && ( bwidth == NB ) )
1299 : {
1300 :
1301 : /*ftmp1 = mean(y_gain4, 10)-0.6f;*/
1302 0 : L_tmp = L_deposit_l( 0 );
1303 0 : FOR( cnt = 0; cnt < 10; cnt++ )
1304 : {
1305 0 : L_tmp = L_mac( L_tmp, y_gain4[cnt], 3277 /*0.1 in Q15*/ );
1306 : }
1307 0 : tmp16 = sub( round_fx( L_tmp ), 4915 );
1308 :
1309 0 : FOR( i = 0; i < Mbands_gn; i++ )
1310 : {
1311 0 : y_gain_tmp2[i] = y_gain4[i];
1312 0 : move16();
1313 : /*if(y_gain4[i] < ftmp1-0.6f)*/
1314 0 : y_gain_tmp2[i] = s_max( y_gain_tmp2[i], tmp16 );
1315 0 : move16();
1316 : }
1317 :
1318 0 : L_tmp = L_deposit_l( 0 );
1319 0 : FOR( i = 0; i < 10; i++ )
1320 : {
1321 0 : L_tmp = L_mac( L_tmp, y_gain_tmp2[i], 3277 /*0.1 in Q15*/ );
1322 : }
1323 :
1324 : /* Quantized mean gain without clipping */
1325 0 : mean_4g[0] = round_fx( L_tmp );
1326 0 : move16();
1327 0 : idx_g = vquant_fx( mean_4g, Gain_meanNB_fx, mean_4g, Gain_mean_dicNB_fx, 1, 64 );
1328 0 : push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
1329 :
1330 0 : FOR( i = 0; i < Mbands_gn; i++ )
1331 : {
1332 0 : y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g[0] );
1333 0 : move16();
1334 : }
1335 : /*if(y_gain_tmp[9] < -0.3f){y_gain_tmp[9] = -0.3f;}*/
1336 0 : y_gain_tmp[9] = s_max( y_gain_tmp[9], -1229 /*0.3 in Q12*/ );
1337 0 : move16();
1338 0 : set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
1339 0 : idx_g = vquant_fx( y_gain_tmp, Mean_dic_NB_fx, y_gain_tmp, Gain_dic1_NB_fx, 3, 64 );
1340 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
1341 :
1342 0 : IF( LT_32( core_brate, ACELP_9k60 ) )
1343 : {
1344 0 : idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NB_fx, 3, 32 );
1345 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
1346 0 : idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NB_fx, 4, 16 );
1347 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
1348 : }
1349 : ELSE
1350 : {
1351 0 : idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NBHR_fx, 3, 64 );
1352 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
1353 0 : idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NBHR_fx, 4, 128 );
1354 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 );
1355 : } /*add end */
1356 :
1357 0 : test();
1358 0 : IF( LE_32( core_brate, ACELP_9k60 ) && ( coder_type == INACTIVE ) )
1359 : {
1360 : /* Some energy is needed in high band for stat_noise_uv_enc
1361 : to be functional in inactive speech */
1362 0 : y_gain_tmp[10] = round_fx( L_mac( L_mac( L_mult( y_gain_tmp[6], 8192 ), y_gain_tmp[7], 8192 ), y_gain_tmp[8], 8192 ) );
1363 0 : move16();
1364 0 : y_gain_tmp[11] = round_fx( L_mac( L_mac( L_mult( y_gain_tmp[7], 8192 ), y_gain_tmp[8], 8192 ), y_gain_tmp[9], 8192 ) );
1365 0 : move16();
1366 :
1367 0 : y_gain_tmp[12] = round_fx( L_mac( L_mac( L_mult( y_gain_tmp[8], 8192 ), y_gain_tmp[9], 8192 ), y_gain_tmp[10], 8192 ) );
1368 0 : move16();
1369 0 : y_gain_tmp[13] = round_fx( L_mac( L_mac( L_mult( y_gain_tmp[9], 8192 ), y_gain_tmp[10], 8192 ), y_gain_tmp[11], 8192 ) );
1370 0 : move16();
1371 0 : y_gain_tmp[14] = round_fx( L_mac( L_mac( L_mult( y_gain_tmp[10], 8192 ), y_gain_tmp[11], 8192 ), y_gain_tmp[12], 8192 ) );
1372 0 : move16();
1373 0 : y_gain_tmp[15] = round_fx( L_mac( L_mac( L_mult( y_gain_tmp[11], 8192 ), y_gain_tmp[12], 8192 ), y_gain_tmp[13], 8192 ) );
1374 0 : move16();
1375 : }
1376 : ELSE
1377 : {
1378 0 : set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
1379 : }
1380 : }
1381 : ELSE
1382 : {
1383 : /*ftmp1 = mean(y_gain4, 16);*/
1384 :
1385 5 : L_tmp = 0;
1386 5 : move32();
1387 85 : FOR( cnt = 0; cnt < 16; cnt++ )
1388 : {
1389 80 : L_tmp = L_mac( L_tmp, y_gain4[cnt], 2048 );
1390 : }
1391 5 : tmp16 = round_fx( L_tmp );
1392 :
1393 5 : tmp1 = sub( tmp16, 4915 );
1394 5 : tmp2 = add( tmp16, 4915 );
1395 5 : L_tmp = 0;
1396 5 : move32();
1397 85 : FOR( i = 0; i < 16; i++ )
1398 : {
1399 80 : y_gain_tmp2[i] = y_gain4[i];
1400 80 : move16();
1401 80 : y_gain_tmp2[i] = s_max( y_gain_tmp2[i], tmp1 );
1402 80 : move16();
1403 80 : y_gain_tmp2[i] = s_min( y_gain_tmp2[i], tmp2 );
1404 80 : move16();
1405 80 : L_tmp = L_mac( L_tmp, y_gain_tmp2[i], 2048 );
1406 : }
1407 5 : FOR( ; i < Mbands_gn; i++ )
1408 : {
1409 0 : y_gain_tmp2[i] = y_gain4[i];
1410 0 : move16();
1411 0 : y_gain_tmp2[i] = s_max( y_gain_tmp2[i], tmp1 ); /* Just the last move is needed, because s_max and s_min could be done in 1 line*/
1412 0 : move16();
1413 0 : y_gain_tmp2[i] = s_min( y_gain_tmp2[i], tmp2 );
1414 0 : move16();
1415 : }
1416 :
1417 : /* Quantized mean gain without clipping */
1418 5 : mean_4g[0] = round_fx( L_tmp );
1419 5 : move16();
1420 :
1421 5 : idx_g = vquant_fx( mean_4g, mean_m_fx, mean_4g, mean_gain_dic_fx, 1, 64 );
1422 5 : push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
1423 :
1424 85 : FOR( i = 0; i < Mbands_gn; i++ )
1425 : {
1426 80 : y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g[0] );
1427 80 : move16();
1428 : }
1429 :
1430 5 : IF( LT_32( core_brate, ACELP_9k60 ) )
1431 : {
1432 : /*mvr2r(y_gain_tmp, y_gain_tmp2, 8); */
1433 0 : Copy( y_gain_tmp, y_gain_tmp2, 8 );
1434 :
1435 0 : y_gain_tmp2[8] = y_gain_tmp[8];
1436 0 : move16();
1437 0 : y_gain_tmp2[9] = y_gain_tmp[10];
1438 0 : move16();
1439 0 : y_gain_tmp2[10] = y_gain_tmp[12];
1440 0 : move16();
1441 0 : y_gain_tmp2[11] = y_gain_tmp[14];
1442 0 : move16();
1443 :
1444 0 : idx_g = 0;
1445 0 : move16();
1446 :
1447 0 : idx_g = vquant_fx( y_gain_tmp2, YGain_mean_LR_fx, y_gain_tmp2, YGain_dic1_LR_fx, 3, 32 );
1448 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
1449 0 : idx_g = vquant_fx( y_gain_tmp2 + 3, YGain_mean_LR_fx + 3, y_gain_tmp2 + 3, YGain_dic2_LR_fx, 4, 32 );
1450 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
1451 0 : idx_g = vquant_fx( y_gain_tmp2 + 7, YGain_mean_LR_fx + 7, y_gain_tmp2 + 7, YGain_dic3_LR_fx, 5, 32 );
1452 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
1453 0 : set16_fx( y_gain_tmp2 + 12, 0, MBANDS_GN - 12 );
1454 :
1455 : /* Update to quantized vector */
1456 0 : Copy( y_gain_tmp2, y_gain_tmp, 8 );
1457 :
1458 0 : Copy( y_gain_tmp2 + 8, y_gain_tmp3, 4 );
1459 0 : set16_fx( y_gain_tmp + 8, 0, 8 );
1460 0 : fft_rel_fx( y_gain_tmp2 + 8, 4, 2 );
1461 :
1462 0 : Copy( y_gain_tmp2 + 8, y_gain_tmp + 8, 3 );
1463 0 : y_gain_tmp[15] = y_gain_tmp2[11];
1464 0 : move16();
1465 0 : ifft_rel_fx( y_gain_tmp + 8, 8, 3 );
1466 :
1467 0 : FOR( i = 8; i < 16; i++ )
1468 : {
1469 0 : y_gain_tmp[i] = shl( mult_r( y_gain_tmp[i], 23101 ), 1 );
1470 0 : move16();
1471 : }
1472 :
1473 0 : y_gain_tmp[8] = y_gain_tmp3[0];
1474 0 : move16();
1475 0 : y_gain_tmp[10] = y_gain_tmp3[1];
1476 0 : move16();
1477 0 : y_gain_tmp[12] = y_gain_tmp3[2];
1478 0 : move16();
1479 0 : y_gain_tmp[14] = y_gain_tmp3[3];
1480 0 : move16();
1481 : }
1482 : ELSE
1483 : {
1484 5 : idx_g = vquant_fx( y_gain_tmp, YG_mean16_fx, y_gain_tmp, YG_dicMR_1_fx, 4, 64 );
1485 5 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
1486 5 : idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16_fx + 4, y_gain_tmp + 4, YG_dicMR_2_fx, 4, 32 );
1487 5 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
1488 5 : idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16_fx + 8, y_gain_tmp + 8, YG_dicMR_3_fx, 4, 32 );
1489 5 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
1490 5 : idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16_fx + 12, y_gain_tmp + 12, YG_dicMR_4_fx, 4, 16 );
1491 5 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
1492 : }
1493 : }
1494 :
1495 : /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
1496 5 : GSC_gain_adj( coder_type, core_brate, mean_4g[0], y_gain_tmp2 /* dummy buffer */, y_gain_tmp, y_gainQ );
1497 :
1498 5 : return mean_4g[0]; /*Q12*/
1499 : }
1500 :
1501 :
1502 : /*-------------------------------------------------------------------*
1503 : * VDQ_vec()
1504 : *
1505 : * Return the dequantized vector of index
1506 : *-------------------------------------------------------------------*/
1507 :
1508 92189 : static Word16 VDQ_vec_fx(
1509 : Word16 *Qvec_out_fx, /* o: Quanitzed vector */
1510 : const Word16 *mean_dic_fx, /* i: average codebook */
1511 : const Word16 *dic_fx, /* i: codebook */
1512 : const Word16 index_fx, /* i: index of codebook*/
1513 : const Word16 vec_en_fx /* i: vector length */
1514 : )
1515 : {
1516 : Word16 i, j;
1517 :
1518 : /*j = shr_r(extract_l(L_mult(index_fx,vec_en_fx)),1);*/
1519 92189 : j = i_mult2( index_fx, vec_en_fx );
1520 394215 : FOR( i = 0; i < vec_en_fx; i++ )
1521 : {
1522 302026 : Qvec_out_fx[i] = dic_fx[j++];
1523 302026 : move16();
1524 : }
1525 :
1526 394215 : FOR( i = 0; i < vec_en_fx; i++ )
1527 : {
1528 302026 : Qvec_out_fx[i] = add( Qvec_out_fx[i], mean_dic_fx[i] );
1529 302026 : move16();
1530 : }
1531 :
1532 92189 : return index_fx;
1533 : }
|