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