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