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 12 : 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 12 : StartBin = 0;
96 12 : move16();
97 12 : NB_Qbins = 0;
98 12 : move16();
99 :
100 12 : tmp_exp = add( 14, sub( Q_exc, Qexc_diff ) ); /* In case of reuse, it can be computed outside the loop*/
101 204 : FOR( i_band = 0; i_band < Mbands_gn; i_band++ )
102 : {
103 192 : StartBin = add( StartBin, NB_Qbins );
104 192 : NB_Qbins = mfreq_bindiv_loc[i_band];
105 192 : move16();
106 192 : IF( EQ_16( ReUseGain, 1 ) )
107 : {
108 96 : y_gain = Ener_per_bd_yQ[i_band];
109 96 : move16();
110 :
111 1632 : FOR( i = StartBin; i < NB_Qbins + StartBin; i++ )
112 : {
113 : #ifdef ISSUE_1836_replace_overflow_libcom
114 1536 : L32 = L_shl_sat( L_mult( exc_diffQ[i], y_gain ), tmp_exp ); /*Q_exc+16 */
115 1536 : exc_diffQ[i] = round_fx_sat( L32 ); /*Q_exc */
116 1536 : 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 96 : L16 = sub( Ener_per_bd_iQ[i_band], Ener_per_bd_yQ[i_band] ); /*Q12 */
131 96 : L32 = L_mult( L16, 27213 ); /* 3.321928 in Q13 -> Q26 */
132 96 : L32 = L_shr( L32, 10 ); /* From Q26 to Q16 */
133 96 : frac = L_Extract_lc( L32, &exp1 ); /* Extract exponent of gcode0 */
134 96 : 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 96 : 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 96 : move16(); /*Q1 */
143 96 : tmp_exp = add( add( exp1, 1 ), sub( Q_exc, Qexc_diff ) );
144 :
145 1632 : FOR( i = StartBin; i < NB_Qbins + StartBin; i++ )
146 : {
147 1536 : L32 = L_mult( exc_diffQ[i], y_gain ); /*Qexc_diff+15 */
148 : #ifdef ISSUE_1836_replace_overflow_libcom
149 1536 : 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 1536 : move16();
154 : }
155 : }
156 : }
157 :
158 12 : return;
159 : }
160 :
161 41374 : 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 41374 : StartBin = 0;
185 41374 : move16();
186 41374 : NB_Qbins = 0;
187 41374 : move16();
188 :
189 41374 : tmp_exp = add( 14, sub( *Q_exc, Qexc_diff ) ); /* In case of reuse, it can be computed outside the loop*/
190 713438 : FOR( i_band = 0; i_band < Mbands_gn; i_band++ )
191 : {
192 672064 : StartBin = add( StartBin, NB_Qbins );
193 672064 : NB_Qbins = mfreq_bindiv_loc[i_band];
194 672064 : move16();
195 672064 : IF( EQ_16( ReUseGain, 1 ) )
196 : {
197 334396 : y_gain = Ener_per_bd_yQ[i_band]; /*Q13*/
198 334396 : move16();
199 :
200 5765692 : FOR( i = StartBin; i < NB_Qbins + StartBin; i++ )
201 : {
202 5431296 : L32 = L_mult( exc_diffQ[i], y_gain ); /*Q_exc+16-tmp_exp */
203 : #ifdef ISSUE_1836_replace_overflow_libcom
204 5431296 : 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 5431296 : move16();
209 5431296 : IF( exc_diffQ[i] )
210 : {
211 419860 : Q_exc_diffQ[i] = sub( *Q_exc, tmp_exp );
212 : }
213 : ELSE
214 : {
215 5011436 : Q_exc_diffQ[i] = *Q_exc;
216 : }
217 5431296 : 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 337668 : L16 = sub_sat( Ener_per_bd_iQ[i_band], Ener_per_bd_yQ[i_band] ); /*Q12 */
227 337668 : L32 = L_mult( L16, 27213 ); /* 3.321928 in Q13 -> Q26 */
228 337668 : L32 = L_shr( L32, 10 ); /* From Q26 to Q16 */
229 337668 : frac = L_Extract_lc( L32, &exp1 ); /* Extract exponent of gcode0 */
230 337668 : 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 337668 : 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 337668 : move16(); /*Q1 */
239 337668 : tmp_exp = add( add( exp1, 1 ), sub( *Q_exc, Qexc_diff ) );
240 :
241 5821444 : FOR( i = StartBin; i < NB_Qbins + StartBin; i++ )
242 : {
243 5483776 : L32 = L_mult( exc_diffQ[i], y_gain ); /*Qexc_diff+15 */
244 : #ifdef ISSUE_1836_replace_overflow_libcom
245 5483776 : 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 5483776 : move16();
250 5483776 : IF( exc_diffQ[i] )
251 : {
252 4883766 : Q_exc_diffQ[i] = sub( *Q_exc, tmp_exp );
253 : }
254 : ELSE
255 : {
256 600010 : Q_exc_diffQ[i] = *Q_exc;
257 : }
258 5483776 : move16();
259 : }
260 : }
261 : }
262 :
263 10956446 : FOR( i = 0; i < StartBin + NB_Qbins; i++ )
264 : {
265 10915072 : *Q_exc = s_min( *Q_exc, add( Q_exc_diffQ[i], norm_s( exc_diffQ[i] ) ) );
266 10915072 : move16();
267 : }
268 10956446 : FOR( i = 0; i < StartBin + NB_Qbins; i++ )
269 : {
270 10915072 : exc_diffQ[i] = shl( exc_diffQ[i], sub( *Q_exc, Q_exc_diffQ[i] ) ); /*Q_exc*/
271 10915072 : move16();
272 : }
273 :
274 41374 : 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 2772670 : 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 2772670 : L_tmp = Calc_Energy_Autoscaled( pt_fx, Q_sc, Len, &ener_exp );
312 2772670 : e_tmp = norm_l( L_tmp );
313 2772670 : f_tmp = Log2_norm_lc( L_shl( L_tmp, e_tmp ) );
314 2772670 : e_tmp = sub( sub( add( 30, E_sc ), e_tmp ), ener_exp );
315 2772670 : L_tmp = Mpy_32_16( e_tmp, f_tmp, 19728 ); /* Q16 */ /*log10(2) in Q17 */
316 2772670 : tmp16 = round_fx( L_shl( L_tmp, 12 - 2 ) ); /* Q12 -1 is to compensate Q17 */
317 2772670 : return tmp16;
318 : }
319 :
320 0 : 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 0 : pt_fx = exc_diff_fx;
332 0 : FOR( j = 0; j < 2; j++ )
333 : {
334 0 : y_gain4_fx[j] = Comp_band_log_ener( pt_fx, 8, Q_exc, 1 ); /*Q12*/
335 0 : move16();
336 0 : pt_fx += 8;
337 : }
338 :
339 0 : FOR( j = 1; j < Mband - 2; j++ )
340 : {
341 0 : y_gain4_fx[j + 1] = Comp_band_log_ener( pt_fx, 16, Q_exc, 0 ); /*Q12*/
342 0 : move16();
343 0 : pt_fx += 16;
344 : }
345 :
346 0 : IF( EQ_16( Eflag, 1 ) )
347 : {
348 0 : y_gain4_fx[j + 1] = Comp_band_log_ener( pt_fx, 32, Q_exc, -1 ); /*Q12*/
349 0 : move16();
350 0 : pt_fx += 32;
351 : }
352 :
353 0 : return;
354 : }
355 :
356 164337 : 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 164337 : pt_fx = exc_diff_fx;
369 493011 : FOR( j = 0; j < 2; j++ )
370 : {
371 328674 : y_gain4_fx[j] = Comp_band_log_ener( pt_fx, 8, Q_exc, 1 ); /*Q12*/
372 328674 : move16();
373 328674 : pt_fx += 8;
374 : }
375 :
376 2300709 : FOR( j = 1; j < Mband - 2; j++ )
377 : {
378 2136372 : y_gain4_fx[j + 1] = Comp_band_log_ener( pt_fx, 16, Q_exc, 0 ); /*Q12*/
379 2136372 : move16();
380 2136372 : pt_fx += 16;
381 : }
382 :
383 164337 : IF( EQ_16( Eflag, 1 ) )
384 : {
385 164316 : y_gain4_fx[j + 1] = Comp_band_log_ener( pt_fx, 32, Q_exc, -1 ); /*Q12*/
386 164316 : move16();
387 164316 : pt_fx += 32;
388 : }
389 :
390 164337 : IF( EQ_16( L_frame, L_FRAME16k ) )
391 : {
392 71654 : y_gain4_fx[j + 2] = Comp_band_log_ener( pt_fx, 32, Q_exc, -1 ); /*Q12*/
393 71654 : move16();
394 71654 : y_gain4_fx[j + 3] = Comp_band_log_ener( pt_fx, 64, Q_exc, -1 ); /*Q12*/
395 71654 : move16();
396 71654 : pt_fx += 64;
397 : }
398 :
399 164337 : return;
400 : }
401 :
402 :
403 : /*-------------------------------------------------------------------*
404 : * gsc_gainQ()
405 : *
406 : * Quantization of the energy per band
407 : *-------------------------------------------------------------------*/
408 :
409 6 : 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 6 : 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 6 : Gain_off = 0;
434 6 : move16();
435 6 : IF( LE_32( core_brate, ACELP_7k20 ) )
436 : {
437 0 : Gain_off = 32767;
438 0 : move16(); /* 8 -> Q12 */
439 : }
440 6 : ELSE IF( LE_32( core_brate, ACELP_8k00 ) )
441 : {
442 0 : Gain_off = 27034;
443 0 : move16(); /* 6.6f -> Q12 */
444 : }
445 6 : ELSE IF( LE_32( core_brate, ACELP_9k60 ) )
446 : {
447 0 : Gain_off = 19661;
448 0 : move16(); /*4.8f-> Q12 */
449 : }
450 6 : ELSE IF( LE_32( core_brate, ACELP_11k60 ) )
451 : {
452 6 : Gain_off = 14336;
453 6 : 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 102 : FOR( i = 0; i < MBANDS_GN; i++ )
463 : {
464 96 : old_y_gain[i] = y_gain_tmp[i];
465 96 : move16();
466 : /*y_gainQ[i] = y_gain_tmp[i]+mean_4g[0]-(i*(Gain_off/20.f)/((float) Mbands_gn));*/
467 96 : 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 96 : move16();
469 : }
470 : }
471 :
472 6 : return;
473 : }
474 :
475 :
476 : /*-------------------------------------------------------------------*
477 : * GSC_gain_adj_ivas_fx()
478 : *
479 : * Quantization of the energy per band
480 : *-------------------------------------------------------------------*/
481 :
482 20585 : 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 20585 : test();
496 20585 : IF( ( coder_type != INACTIVE ) && NE_16( coder_type, UNVOICED ) )
497 : {
498 166379 : FOR( i = 0; i < Mbands_gn; i++ )
499 : {
500 156592 : old_y_gain[i] = y_gain_tmp[i];
501 156592 : move16();
502 156592 : y_gainQ[i] = add( y_gain_tmp[i], mean_g );
503 156592 : move16();
504 : }
505 : }
506 : ELSE
507 : {
508 10798 : Gain_off = 0;
509 10798 : move16();
510 :
511 10798 : test();
512 10798 : IF( LE_32( core_brate, ACELP_5k00 ) && EQ_16( coder_type, UNVOICED ) )
513 : {
514 8 : Gain_off = 18432;
515 8 : move16(); /* 9 -> Q11 */
516 : }
517 10798 : IF( LE_32( core_brate, ACELP_7k20 ) )
518 : {
519 6728 : Gain_off = 16384;
520 6728 : move16(); /* 8 -> Q11 */
521 : }
522 4070 : ELSE IF( LE_32( core_brate, ACELP_8k00 ) )
523 : {
524 13 : Gain_off = 13517;
525 13 : move16(); /* 6.6f -> Q11 */
526 : }
527 4057 : ELSE IF( LE_32( core_brate, ACELP_9k60 ) )
528 : {
529 354 : Gain_off = 9830;
530 354 : move16(); /*4.8f-> Q11 */
531 : }
532 3703 : ELSE IF( LE_32( core_brate, ACELP_11k60 ) )
533 : {
534 154 : Gain_off = 7168;
535 154 : move16(); /* 3.5f -> Q11 */
536 : }
537 3549 : ELSE IF( LE_32( core_brate, ACELP_13k20 ) )
538 : {
539 382 : Gain_off = 6144;
540 382 : move16(); /* 3.0f -> Q11 dB */
541 : }
542 :
543 : /*mimic ACELP decay of energy for low rates*/
544 188632 : FOR( i = 0; i < Mbands_gn; i++ )
545 : {
546 177834 : old_y_gain[i] = y_gain_tmp[i];
547 177834 : move16();
548 177834 : 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 177834 : move16();
550 : }
551 : }
552 :
553 20585 : 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 0 : 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 0 : Gain_off = 0;
580 0 : move16();
581 :
582 0 : test();
583 0 : IF( coder_type == INACTIVE || EQ_16( coder_type, UNVOICED ) )
584 : {
585 0 : test();
586 0 : 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 0 : ELSE IF( LE_32( core_brate, ACELP_7k20 ) )
592 : {
593 0 : Gain_off = 1638; // 8/20 in Q12; /* 0 dB */
594 0 : move16();
595 : }
596 0 : ELSE IF( LE_32( core_brate, ACELP_8k00 ) )
597 : {
598 0 : Gain_off = 1351; // 6.6f/20 in Q12 /* ~-3.3 dB */
599 0 : move16();
600 : }
601 0 : ELSE IF( LE_32( core_brate, ACELP_9k60 ) )
602 : {
603 0 : Gain_off = 983; // 4.8f/20 in Q12 /* ~-2.4 dB */
604 0 : move16();
605 : }
606 0 : ELSE IF( LE_32( core_brate, ACELP_11k60 ) )
607 : {
608 0 : Gain_off = 717; // 3.5f/20 in Q12 /* ~-2.4 dB */
609 0 : move16();
610 : }
611 0 : ELSE IF( LE_32( core_brate, ACELP_13k20 ) )
612 : {
613 0 : Gain_off = 614; // 3.0f/20 in Q12 /* ~-2.4 dB */
614 0 : move16();
615 : }
616 : }
617 :
618 0 : test();
619 0 : IF( coder_type != INACTIVE && NE_16( coder_type, UNVOICED ) )
620 : {
621 0 : FOR( i = 0; i < Mbands_gn; i++ )
622 : {
623 0 : Gain_out[i] = add( Gain_in[i], mean_g ); // Q12
624 0 : move16();
625 : }
626 : }
627 : ELSE
628 : {
629 : /*mimic ACELP decay of energy for low rates*/
630 0 : test();
631 0 : 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 0 : FOR( i = 0; i < Mbands_gn; i++ )
644 : {
645 0 : Gain_out[i] = add( Gain_in[i], sub( mean_g, mult( Gain_off, div_s( i, Mbands_gn ) ) ) ); // Q12
646 0 : move16();
647 : // Gain_out[i] = Gain_in[i] + mean_g - ( i * ( Gain_off / 20.f ) / ( (float) Mbands_gn ) );
648 : }
649 : }
650 : }
651 :
652 0 : return;
653 : }
654 :
655 :
656 : /*-------------------------------------------------------------------*
657 : * gsc_gainQ()
658 : *
659 : * Quantization of the energy per band
660 : *-------------------------------------------------------------------*/
661 :
662 0 : 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 0 : Word16 i, idx_g = 0;
681 0 : move16();
682 : Word16 mean_4g_fx[1], ftmp1_fx;
683 0 : Word16 Mbands_gn = MBANDS_GN;
684 0 : move16();
685 : Word16 y_gain_tmp3[MBANDS_GN];
686 : Word32 L_tmp;
687 :
688 0 : if ( EQ_16( L_frame, L_FRAME16k ) )
689 : {
690 0 : Mbands_gn = MBANDS_GN16k;
691 0 : move16();
692 : }
693 :
694 0 : mean_4g_fx[0] = 0;
695 0 : move32();
696 :
697 0 : test();
698 0 : test();
699 0 : 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 0 : L_tmp = 0;
793 0 : move32();
794 0 : FOR( i = 0; i < 16; i++ )
795 : {
796 0 : L_tmp = L_add( L_tmp, y_gain4[i] );
797 : }
798 0 : L_tmp = Mpy_32_16_1( L_tmp, 2048 /* (1/16.f) in Q15 */ ); // Q12
799 0 : ftmp1_fx = extract_l( L_tmp );
800 0 : FOR( i = 0; i < Mbands_gn; i++ )
801 : {
802 0 : IF( LT_16( y_gain4[i], sub( ftmp1_fx, 2457 /* 0.6 in Q12*/ ) ) )
803 : {
804 0 : y_gain_tmp2[i] = sub( ftmp1_fx, 2457 /* 0.6 in Q12*/ );
805 : }
806 0 : ELSE IF( GT_16( y_gain4[i], add( ftmp1_fx, 2457 /* 0.6 in Q12*/ ) ) )
807 : {
808 0 : y_gain_tmp2[i] = add( ftmp1_fx, 2457 /* 0.6 in Q12*/ );
809 : }
810 : ELSE
811 : {
812 0 : y_gain_tmp2[i] = y_gain4[i];
813 : }
814 0 : move16();
815 : }
816 :
817 0 : L_tmp = 0;
818 0 : move32();
819 0 : FOR( i = 0; i < 16; i++ )
820 : {
821 0 : L_tmp = L_add( L_tmp, y_gain_tmp2[i] );
822 : }
823 0 : L_tmp = Mpy_32_16_1( L_tmp, 2048 /* (1/16.f) in Q15 */ ); // Q12
824 0 : mean_4g_fx[0] = extract_l( L_tmp ); // Q12
825 0 : move16();
826 0 : idx_g = vquant_fx( mean_4g_fx, mean_m_fx, mean_4g_fx, mean_gain_dic_fx, 1, 64 );
827 0 : push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
828 :
829 : /* Subtraction of the average gain */
830 0 : FOR( i = 0; i < Mbands_gn; i++ )
831 : {
832 0 : y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g_fx[0] ); // Q12
833 0 : move16();
834 : }
835 :
836 0 : 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 0 : Copy( y_gain_tmp, y_gain_tmp2, 8 );
846 :
847 0 : y_gain_tmp2[8] = y_gain_tmp[8];
848 0 : move16();
849 0 : y_gain_tmp2[9] = y_gain_tmp[10];
850 0 : move16();
851 0 : y_gain_tmp2[10] = y_gain_tmp[12];
852 0 : move16();
853 0 : y_gain_tmp2[11] = y_gain_tmp[14];
854 0 : move16();
855 :
856 0 : idx_g = 0;
857 0 : move16();
858 0 : idx_g = vquant_fx( y_gain_tmp2, YGain_mean_LR_fx, y_gain_tmp2, YGain_dic1_LR_fx, 3, 32 );
859 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
860 :
861 0 : test();
862 0 : test();
863 0 : test();
864 0 : IF( !( coder_type == INACTIVE && tdm_LRTD_flag == 0 && EQ_16( idchan, 1 ) ) || GT_32( core_brate_inp, GSC_LRES_GAINQ_LIMIT ) )
865 : {
866 0 : idx_g = vquant_fx( y_gain_tmp2 + 3, YGain_mean_LR_fx + 3, y_gain_tmp2 + 3, YGain_dic2_LR_fx, 4, 32 );
867 0 : 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 0 : idx_g = vquant_fx( y_gain_tmp2 + 7, YGain_mean_LR_fx + 7, y_gain_tmp2 + 7, YGain_dic3_LR_fx, 5, 32 );
875 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
876 :
877 0 : set16_fx( y_gain_tmp2 + 12, 0, MBANDS_GN - 12 );
878 :
879 : /* Update to quantized vector */
880 0 : Copy( y_gain_tmp2, y_gain_tmp, 8 );
881 :
882 0 : Copy( y_gain_tmp2 + 8, y_gain_tmp3, 4 );
883 0 : set16_fx( y_gain_tmp + 8, 0, 8 );
884 0 : fft_rel_fx( y_gain_tmp2 + 8, 4, 2 );
885 :
886 0 : Copy( y_gain_tmp2 + 8, y_gain_tmp + 8, 3 );
887 0 : y_gain_tmp[15] = y_gain_tmp2[11];
888 0 : move16();
889 0 : ifft_rel_fx( y_gain_tmp + 8, 8, 3 );
890 :
891 0 : FOR( i = 8; i < 16; i++ )
892 : {
893 0 : y_gain_tmp[i] = shl( mult( y_gain_tmp[i], 23101 /* 1.41 in Q14 */ ), 1 ); /*Q12*/
894 0 : move16();
895 : }
896 :
897 0 : y_gain_tmp[8] = y_gain_tmp3[0];
898 0 : move16();
899 0 : y_gain_tmp[10] = y_gain_tmp3[1];
900 0 : move16();
901 0 : y_gain_tmp[12] = y_gain_tmp3[2];
902 0 : move16();
903 0 : y_gain_tmp[14] = y_gain_tmp3[3];
904 0 : 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 0 : IF( EQ_16( L_frame, L_FRAME ) )
915 : {
916 0 : idx_g = vquant_fx( y_gain_tmp, YG_mean16_fx, y_gain_tmp, YG_dicMR_1_fx, 4, 64 );
917 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
918 :
919 0 : idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16_fx + 4, y_gain_tmp + 4, YG_dicMR_2_fx, 4, 32 );
920 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
921 :
922 0 : idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16_fx + 8, y_gain_tmp + 8, YG_dicMR_3_fx, 4, 32 );
923 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
924 :
925 0 : idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16_fx + 12, y_gain_tmp + 12, YG_dicMR_4_fx, 4, 16 );
926 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
927 : }
928 : ELSE
929 : {
930 0 : idx_g = vquant_fx( y_gain_tmp, YG_mean16HR_fx, y_gain_tmp, YG_dicHR_1_fx, 4, 128 );
931 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 );
932 :
933 0 : idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16HR_fx + 4, y_gain_tmp + 4, YG_dicHR_2_fx, 4, 64 );
934 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
935 :
936 0 : idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16HR_fx + 8, y_gain_tmp + 8, YG_dicHR_3_fx, 4, 64 );
937 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
938 :
939 0 : idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16HR_16kHz_fx, y_gain_tmp + 12, YG_dicHR_4_16kHz_fx, 4, 64 );
940 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
941 :
942 0 : idx_g = vquant_fx( y_gain_tmp + 16, YG_meanL2G_16kHz_fx, y_gain_tmp + 16, YG_dicL2G_16kHz_fx, 2, 8 );
943 0 : push_indice( hBstr, IND_Y_GAIN_HF, idx_g, 3 );
944 : }
945 : }
946 : }
947 :
948 0 : GSC_gain_DQ_fx( element_mode, ENC, coder_type, Mbands_gn, core_brate, mean_4g_fx[0], y_gain_tmp, y_gainQ );
949 :
950 0 : 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 6 : 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 6 : test();
989 6 : test();
990 6 : 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 6 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1040 :
1041 6 : VDQ_vec_fx( &mean_4g_fx, mean_m_fx, mean_gain_dic_fx, idx_g_fx, 1 );
1042 :
1043 6 : 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 6 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1093 6 : VDQ_vec_fx( y_gainQ_fx, YG_mean16_fx, YG_dicMR_1_fx, idx_g_fx, 4 );
1094 :
1095 6 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1096 6 : VDQ_vec_fx( y_gainQ_fx + 4, YG_mean16_fx + 4, YG_dicMR_2_fx, idx_g_fx, 4 );
1097 :
1098 6 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1099 6 : VDQ_vec_fx( y_gainQ_fx + 8, YG_mean16_fx + 8, YG_dicMR_3_fx, idx_g_fx, 4 );
1100 :
1101 6 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 4 );
1102 6 : 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 6 : GSC_gain_adj( coder_type, core_brate_fx, mean_4g_fx, old_y_gain_fx, y_gainQ_fx, y_gainQ_fx );
1108 :
1109 6 : 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 20585 : 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 20585 : Word16 Mbands_gn = MBANDS_GN;
1146 20585 : move16();
1147 : Word16 y_gain_tmp3_fx[MBANDS_GN];
1148 20585 : if ( EQ_16( st_fx->L_frame, L_FRAME16k ) )
1149 : {
1150 2533 : Mbands_gn = MBANDS_GN16k;
1151 2533 : move16();
1152 : }
1153 :
1154 20585 : test();
1155 20585 : test();
1156 20585 : 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 20585 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1206 :
1207 20585 : VDQ_vec_fx( &mean_4g_fx, mean_m_fx, mean_gain_dic_fx, idx_g_fx, 1 );
1208 :
1209 20585 : 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 13145 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1215 13145 : VDQ_vec_fx( y_gainQ_fx, YGain_mean_LR_fx, YGain_dic1_LR_fx, idx_g_fx, 3 );
1216 :
1217 13145 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1218 13145 : 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 13145 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1226 :
1227 13145 : VDQ_vec_fx( y_gainQ_fx + 7, YGain_mean_LR_fx + 7, YGain_dic3_LR_fx, idx_g_fx, 5 );
1228 :
1229 13145 : Copy( y_gainQ_fx + 8, y_gain_tmp3_fx, 4 );
1230 13145 : set16_fx( y_gainQ_fx + 12, 0, 4 );
1231 :
1232 13145 : fft_rel_fx( y_gainQ_fx + 8, 4, 2 );
1233 :
1234 13145 : y_gainQ_fx[15] = y_gainQ_fx[11];
1235 13145 : move16();
1236 13145 : y_gainQ_fx[11] = 0;
1237 13145 : move16();
1238 13145 : ifft_rel_fx( y_gainQ_fx + 8, 8, 3 );
1239 118305 : FOR( i = 8; i < 16; i++ )
1240 : {
1241 105160 : y_gainQ_fx[i] = round_fx( L_shl( L_mult( y_gainQ_fx[i], 23101 ), 1 ) ); /*Q12 */
1242 105160 : move16();
1243 : }
1244 : /*----------------------------------------------------------------------*
1245 : * Copy the true Q values in the specific bands
1246 : *----------------------------------------------------------------------*/
1247 13145 : y_gainQ_fx[8] = y_gain_tmp3_fx[0]; /*Q12*/
1248 13145 : move16();
1249 13145 : y_gainQ_fx[10] = y_gain_tmp3_fx[1]; /*Q12*/
1250 13145 : move16();
1251 13145 : y_gainQ_fx[12] = y_gain_tmp3_fx[2]; /*Q12*/
1252 13145 : move16();
1253 13145 : y_gainQ_fx[14] = y_gain_tmp3_fx[3]; /*Q12*/
1254 13145 : move16();
1255 : }
1256 : ELSE
1257 : {
1258 7440 : IF( EQ_16( st_fx->L_frame, L_FRAME ) )
1259 : {
1260 4907 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1261 4907 : VDQ_vec_fx( y_gainQ_fx, YG_mean16_fx, YG_dicMR_1_fx, idx_g_fx, 4 );
1262 :
1263 4907 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1264 4907 : VDQ_vec_fx( y_gainQ_fx + 4, YG_mean16_fx + 4, YG_dicMR_2_fx, idx_g_fx, 4 );
1265 :
1266 4907 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
1267 4907 : VDQ_vec_fx( y_gainQ_fx + 8, YG_mean16_fx + 8, YG_dicMR_3_fx, idx_g_fx, 4 );
1268 :
1269 4907 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 4 );
1270 4907 : VDQ_vec_fx( y_gainQ_fx + 12, YG_mean16_fx + 12, YG_dicMR_4_fx, idx_g_fx, 4 );
1271 : }
1272 : ELSE
1273 : {
1274 2533 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 7 );
1275 2533 : VDQ_vec_fx( y_gainQ_fx, YG_mean16HR_fx, YG_dicHR_1_fx, idx_g_fx, 4 );
1276 :
1277 2533 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1278 2533 : VDQ_vec_fx( y_gainQ_fx + 4, YG_mean16HR_fx + 4, YG_dicHR_2_fx, idx_g_fx, 4 );
1279 :
1280 2533 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1281 2533 : VDQ_vec_fx( y_gainQ_fx + 8, YG_mean16HR_fx + 8, YG_dicHR_3_fx, idx_g_fx, 4 );
1282 :
1283 2533 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
1284 2533 : VDQ_vec_fx( y_gainQ_fx + 12, YG_mean16HR_16kHz_fx, YG_dicHR_4_16kHz_fx, idx_g_fx, 4 );
1285 :
1286 2533 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 3 );
1287 2533 : 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 20585 : 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 20585 : return mean_4g_fx;
1296 : }
1297 :
1298 :
1299 : /*-------------------------------------------------------------------*
1300 : * gsc_gainQ()
1301 : *
1302 : * Quantization of the energy per band
1303 : *-------------------------------------------------------------------*/
1304 :
1305 0 : 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 0 : Word16 i, idx_g = 0;
1316 0 : move16();
1317 0 : Word16 mean_4g[1] = { 0 }, tmp16, tmp1, tmp2;
1318 0 : move16();
1319 0 : Word16 Mbands_gn = MBANDS_GN;
1320 : Word16 y_gain_tmp3[MBANDS_GN];
1321 : Word16 cnt;
1322 : Word32 L_tmp;
1323 :
1324 0 : mean_4g[0] = 0;
1325 :
1326 0 : test();
1327 0 : test();
1328 0 : 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 0 : L_tmp = 0;
1416 0 : move32();
1417 0 : FOR( cnt = 0; cnt < 16; cnt++ )
1418 : {
1419 0 : L_tmp = L_mac( L_tmp, y_gain4[cnt], 2048 );
1420 : }
1421 0 : tmp16 = round_fx( L_tmp );
1422 :
1423 0 : tmp1 = sub( tmp16, 4915 );
1424 0 : tmp2 = add( tmp16, 4915 );
1425 0 : L_tmp = 0;
1426 0 : move32();
1427 0 : FOR( i = 0; i < 16; i++ )
1428 : {
1429 0 : y_gain_tmp2[i] = y_gain4[i];
1430 0 : move16();
1431 0 : y_gain_tmp2[i] = s_max( y_gain_tmp2[i], tmp1 );
1432 0 : move16();
1433 0 : y_gain_tmp2[i] = s_min( y_gain_tmp2[i], tmp2 );
1434 0 : move16();
1435 0 : L_tmp = L_mac( L_tmp, y_gain_tmp2[i], 2048 );
1436 : }
1437 0 : 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 0 : mean_4g[0] = round_fx( L_tmp );
1449 0 : move16();
1450 :
1451 0 : idx_g = vquant_fx( mean_4g, mean_m_fx, mean_4g, mean_gain_dic_fx, 1, 64 );
1452 0 : push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
1453 :
1454 0 : FOR( i = 0; i < Mbands_gn; i++ )
1455 : {
1456 0 : y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g[0] );
1457 0 : move16();
1458 : }
1459 :
1460 0 : 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 0 : idx_g = vquant_fx( y_gain_tmp, YG_mean16_fx, y_gain_tmp, YG_dicMR_1_fx, 4, 64 );
1515 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
1516 0 : idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16_fx + 4, y_gain_tmp + 4, YG_dicMR_2_fx, 4, 32 );
1517 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
1518 0 : idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16_fx + 8, y_gain_tmp + 8, YG_dicMR_3_fx, 4, 32 );
1519 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
1520 0 : idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16_fx + 12, y_gain_tmp + 12, YG_dicMR_4_fx, 4, 16 );
1521 0 : 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 0 : GSC_gain_adj( coder_type, core_brate, mean_4g[0], y_gain_tmp2 /* dummy buffer */, y_gain_tmp, y_gainQ );
1527 :
1528 0 : return mean_4g[0]; /*Q12*/
1529 : }
1530 :
1531 :
1532 : /*-------------------------------------------------------------------*
1533 : * VDQ_vec()
1534 : *
1535 : * Return the dequantized vector of index
1536 : *-------------------------------------------------------------------*/
1537 :
1538 92343 : 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 92343 : j = i_mult2( index_fx, vec_en_fx );
1550 394876 : FOR( i = 0; i < vec_en_fx; i++ )
1551 : {
1552 302533 : Qvec_out_fx[i] = dic_fx[j++];
1553 302533 : move16();
1554 : }
1555 :
1556 394876 : FOR( i = 0; i < vec_en_fx; i++ )
1557 : {
1558 302533 : Qvec_out_fx[i] = add( Qvec_out_fx[i], mean_dic_fx[i] );
1559 302533 : move16();
1560 : }
1561 :
1562 92343 : return index_fx;
1563 : }
|