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 "options.h" /* Compilation switches */
38 : #include "cnst.h" /* Common constants */
39 : #include "rom_com.h" /* Static table prototypes */
40 : #include "prot_fx.h"
41 : #include "stl.h"
42 :
43 : /*-------------------------------------------------------------------*
44 : * Local constants
45 : *-------------------------------------------------------------------*/
46 :
47 : 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 );
48 :
49 : /*========================================================================*/
50 : /* FUNCTION : void Comp_and_apply_gain_enc_fx */
51 : /*------------------------------------------------------------------------*/
52 : /* PURPOSE : Compute and apply the quantized per band gain */
53 : /*------------------------------------------------------------------------*/
54 : /* INPUT ARGUMENTS : */
55 : /* _ (Word16[]) Ener_per_bd_iQ : Target ener per band Q12 */
56 : /*------------------------------------------------------------------------*/
57 : /* INPUT/OUTPUT ARGUMENTS : */
58 : /* _ (Word16[]) exc_diffQ : Quantized excitation Qexc */
59 : /* _ (Word16[]) Ener_per_bd_yQ : Ener per band for norm vectori->Q12/o->Q2*/
60 : /*------------------------------------------------------------------------*/
61 : /* OUTPUT ARGUMENTS : */
62 : /* _ None */
63 : /*------------------------------------------------------------------------*/
64 :
65 : /*------------------------------------------------------------------------*/
66 : /* RETURN ARGUMENTS : */
67 : /* _ None */
68 : /*========================================================================*/
69 26 : void Comp_and_apply_gain_fx(
70 : Word16 exc_diffQ[], /* i/o: Quantized excitation */
71 : Word16 Ener_per_bd_iQ[], /* i : Target ener per band Q13 */
72 : Word16 Ener_per_bd_yQ[], /* i/o : Ener per band for norm vector i->Q13/o->Q13 */
73 : Word16 Mbands_gn, /* i : number of bands */
74 : const Word16 ReUseGain, /* i : Reuse the gain in Ener_per_bd_yQ */
75 : Word16 Qexc_diff,
76 : Word16 Q_exc )
77 : {
78 : Word16 i, i_band;
79 : Word16 StartBin, NB_Qbins;
80 : Word16 y_gain;
81 : Word16 L16, frac, exp1, tmp_exp;
82 : Word32 L32;
83 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
84 26 : Flag Overflow = 0;
85 26 : move32();
86 : #endif
87 :
88 : /* Recreate excitation for local synthesis and decoder */
89 26 : StartBin = 0;
90 26 : move16();
91 26 : NB_Qbins = 0;
92 26 : move16();
93 :
94 26 : tmp_exp = add( 14, sub( Q_exc, Qexc_diff ) ); /* In case of reuse, it can be computed outside the loop*/
95 442 : FOR( i_band = 0; i_band < Mbands_gn; i_band++ )
96 : {
97 416 : StartBin = add( StartBin, NB_Qbins );
98 416 : NB_Qbins = mfreq_bindiv_loc[i_band];
99 416 : move16();
100 416 : IF( EQ_16( ReUseGain, 1 ) )
101 : {
102 208 : y_gain = Ener_per_bd_yQ[i_band];
103 208 : move16();
104 :
105 3536 : FOR( i = StartBin; i < NB_Qbins + StartBin; i++ )
106 : {
107 3328 : L32 = L_shl_o( L_mult( exc_diffQ[i], y_gain ), tmp_exp, &Overflow ); /*Q_exc+16 */
108 3328 : exc_diffQ[i] = round_fx_o( L32, &Overflow ); /*Q_exc */
109 3328 : move16();
110 : }
111 : }
112 : ELSE
113 : {
114 : /*-----------------------------------------------------------------*
115 : * y_gain = pow(10.0, (Ener_per_bd_iQ[i_band]-Ener_per_bd_yQ[i_band]))
116 : * = pow(2, 3.321928*(Ener_per_bd_iQ[i_band]-Ener_per_bd_yQ[i_band]))
117 : *-----------------------------------------------------------------*/
118 208 : L16 = sub( Ener_per_bd_iQ[i_band], Ener_per_bd_yQ[i_band] ); /*Q12 */
119 208 : L32 = L_mult( L16, 27213 ); /* 3.321928 in Q13 -> Q26 */
120 208 : L32 = L_shr( L32, 10 ); /* From Q26 to Q16 */
121 208 : frac = L_Extract_lc( L32, &exp1 ); /* Extract exponent of gcode0 */
122 208 : y_gain = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
123 : /* output of Pow2() will be: */
124 : /* 16384 < Pow2() <= 32767 */
125 208 : Ener_per_bd_yQ[i_band] = shl_o( y_gain, sub( exp1, 13 ), &Overflow );
126 208 : move16(); /*Q1 */
127 208 : tmp_exp = add( add( exp1, 1 ), sub( Q_exc, Qexc_diff ) );
128 :
129 3536 : FOR( i = StartBin; i < NB_Qbins + StartBin; i++ )
130 : {
131 3328 : L32 = L_mult( exc_diffQ[i], y_gain ); /*Qexc_diff+15 */
132 3328 : exc_diffQ[i] = round_fx_o( L_shl_o( L32, tmp_exp, &Overflow ), &Overflow ); /*Q_exc */
133 3328 : move16();
134 : }
135 : }
136 : }
137 :
138 26 : return;
139 : }
140 :
141 86702 : void Comp_and_apply_gain_ivas_fx(
142 : Word16 exc_diffQ[], /* i/o: Quantized excitation */
143 : Word16 Ener_per_bd_iQ[], /* i : Target ener per band Q13 */
144 : Word16 Ener_per_bd_yQ[], /* i/o : Ener per band for norm vector i->Q13/o->Q13 */
145 : Word16 Mbands_gn, /* i : number of bands */
146 : const Word16 ReUseGain, /* i : Reuse the gain in Ener_per_bd_yQ */
147 : Word16 Qexc_diff,
148 : Word16 *Q_exc )
149 : {
150 : Word16 i, i_band;
151 : Word16 StartBin, NB_Qbins;
152 : Word16 y_gain;
153 : Word16 L16, frac, exp1, tmp_exp;
154 : Word32 L32;
155 : Word16 Q_exc_diffQ[L_FRAME16k];
156 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
157 86702 : Flag Overflow = 0;
158 86702 : move32();
159 : #endif
160 :
161 : /* Recreate excitation for local synthesis and decoder */
162 86702 : StartBin = 0;
163 86702 : move16();
164 86702 : NB_Qbins = 0;
165 86702 : move16();
166 :
167 86702 : tmp_exp = add( 14, sub( *Q_exc, Qexc_diff ) ); /* In case of reuse, it can be computed outside the loop*/
168 1494352 : FOR( i_band = 0; i_band < Mbands_gn; i_band++ )
169 : {
170 1407650 : StartBin = add( StartBin, NB_Qbins );
171 1407650 : NB_Qbins = mfreq_bindiv_loc[i_band];
172 1407650 : move16();
173 1407650 : IF( EQ_16( ReUseGain, 1 ) )
174 : {
175 702205 : y_gain = Ener_per_bd_yQ[i_band]; /*Q13*/
176 702205 : move16();
177 :
178 12102621 : FOR( i = StartBin; i < NB_Qbins + StartBin; i++ )
179 : {
180 11400416 : L32 = L_mult( exc_diffQ[i], y_gain ); /*Q_exc+16-tmp_exp */
181 11400416 : exc_diffQ[i] = round_fx_o( L32, &Overflow ); /*Q_exc-tmp_exp */
182 11400416 : move16();
183 11400416 : IF( exc_diffQ[i] )
184 : {
185 881244 : Q_exc_diffQ[i] = sub( *Q_exc, tmp_exp );
186 : }
187 : ELSE
188 : {
189 10519172 : Q_exc_diffQ[i] = *Q_exc;
190 : }
191 11400416 : move16();
192 : }
193 : }
194 : ELSE
195 : {
196 : /*-----------------------------------------------------------------*
197 : * y_gain = pow(10.0, (Ener_per_bd_iQ[i_band]-Ener_per_bd_yQ[i_band]))
198 : * = pow(2, 3.321928*(Ener_per_bd_iQ[i_band]-Ener_per_bd_yQ[i_band]))
199 : *-----------------------------------------------------------------*/
200 705445 : L16 = sub_sat( Ener_per_bd_iQ[i_band], Ener_per_bd_yQ[i_band] ); /*Q12 */
201 705445 : L32 = L_mult( L16, 27213 ); /* 3.321928 in Q13 -> Q26 */
202 705445 : L32 = L_shr( L32, 10 ); /* From Q26 to Q16 */
203 705445 : frac = L_Extract_lc( L32, &exp1 ); /* Extract exponent of gcode0 */
204 705445 : y_gain = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
205 : /* output of Pow2() will be: */
206 : /* 16384 < Pow2() <= 32767 */
207 705445 : Ener_per_bd_yQ[i_band] = shl_o( y_gain, sub( exp1, 13 ), &Overflow ); /*Q13*/
208 705445 : move16(); /*Q1 */
209 705445 : tmp_exp = add( add( exp1, 1 ), sub( *Q_exc, Qexc_diff ) );
210 :
211 12157829 : FOR( i = StartBin; i < NB_Qbins + StartBin; i++ )
212 : {
213 11452384 : L32 = L_mult( exc_diffQ[i], y_gain ); /*Qexc_diff+15 */
214 11452384 : exc_diffQ[i] = round_fx_o( L32, &Overflow ); /*Q_exc-tmp_exp */
215 11452384 : move16();
216 11452384 : IF( exc_diffQ[i] )
217 : {
218 10186702 : Q_exc_diffQ[i] = sub( *Q_exc, tmp_exp );
219 : }
220 : ELSE
221 : {
222 1265682 : Q_exc_diffQ[i] = *Q_exc;
223 : }
224 11452384 : move16();
225 : }
226 : }
227 : }
228 :
229 22939502 : FOR( i = 0; i < StartBin + NB_Qbins; i++ )
230 : {
231 22852800 : *Q_exc = s_min( *Q_exc, add( Q_exc_diffQ[i], norm_s( exc_diffQ[i] ) ) );
232 22852800 : move16();
233 : }
234 22939502 : FOR( i = 0; i < StartBin + NB_Qbins; i++ )
235 : {
236 22852800 : exc_diffQ[i] = shl( exc_diffQ[i], sub( *Q_exc, Q_exc_diffQ[i] ) ); /*Q_exc*/
237 22852800 : move16();
238 : }
239 :
240 86702 : return;
241 : }
242 :
243 :
244 : /*========================================================================*/
245 : /* FUNCTION : Ener_per_band_comp_fx() */
246 : /*------------------------------------------------------------------------*/
247 : /* PURPOSE : Compute the energy per band in log domain for quantization */
248 : /* purposes. */
249 : /* Loops are decomposed to accomodate the PVQ quantization */
250 : /*------------------------------------------------------------------------*/
251 : /* INPUT ARGUMENTS : */
252 : /* _ (Word16*) edct_table_128_fx : edct table Q15 */
253 : /* _ (Word16*) Q_exc_diff : input format of exc_diff */
254 : /*------------------------------------------------------------------------*/
255 : /* INPUT/OUTPUT ARGUMENTS : */
256 : /*------------------------------------------------------------------------*/
257 : /* OUTPUT ARGUMENTS : */
258 : /* _ (Word16[]) y_gain4 : Energy per band to quantize Q12 */
259 : /* _ (Word32*) etmp14 : Energy band 14 Q_exc_diff*2+1 */
260 : /* _ (Word32*) etmp15 : Energy band 15 Q_exc_diff*2+1 */
261 : /*------------------------------------------------------------------------*/
262 :
263 : /*------------------------------------------------------------------------*/
264 : /* RETURN ARGUMENTS : */
265 : /* _ None */
266 : /*========================================================================*/
267 3468605 : static Word16 Comp_band_log_ener( /* o : Band gain Q12 */
268 : const Word16 *pt_fx, /* i : Dct input Q_sc */
269 : const Word16 Len, /* i : Lenght en energy accumulation */
270 : const Word16 Q_sc, /* i : scaling of input */
271 : const Word16 E_sc /* i : Additional scaling factor for energy */
272 : )
273 : {
274 : Word32 L_tmp;
275 : Word16 e_tmp, f_tmp, tmp16, ener_exp;
276 3468605 : L_tmp = Calc_Energy_Autoscaled( pt_fx, Q_sc, Len, &ener_exp );
277 3468605 : e_tmp = norm_l( L_tmp );
278 3468605 : f_tmp = Log2_norm_lc( L_shl( L_tmp, e_tmp ) );
279 3468605 : e_tmp = sub( sub( add( 30, E_sc ), e_tmp ), ener_exp );
280 3468605 : L_tmp = Mpy_32_16( e_tmp, f_tmp, 19728 ); /* Q16 */ /*log10(2) in Q17 */
281 3468605 : tmp16 = round_fx( L_shl( L_tmp, 12 - 2 ) ); /* Q12 -1 is to compensate Q17 */
282 3468605 : return tmp16;
283 : }
284 :
285 14 : void Ener_per_band_comp_fx(
286 : const Word16 exc_diff_fx[], /* i : target signal Q_exc_diff */
287 : Word16 y_gain4_fx[], /* o : Energy per band to quantize Q12 */
288 : const Word16 Q_exc, /* i : frame length */
289 : const Word16 Mband, /* i : Max band */
290 : const Word16 Eflag /* i : flag of highest band */
291 : )
292 : {
293 : const Word16 *pt_fx;
294 : Word16 j;
295 :
296 14 : pt_fx = exc_diff_fx;
297 42 : FOR( j = 0; j < 2; j++ )
298 : {
299 28 : y_gain4_fx[j] = Comp_band_log_ener( pt_fx, 8, Q_exc, 1 ); /*Q12*/
300 28 : move16();
301 28 : pt_fx += 8;
302 : }
303 :
304 196 : FOR( j = 1; j < Mband - 2; j++ )
305 : {
306 182 : y_gain4_fx[j + 1] = Comp_band_log_ener( pt_fx, 16, Q_exc, 0 ); /*Q12*/
307 182 : move16();
308 182 : pt_fx += 16;
309 : }
310 :
311 14 : IF( EQ_16( Eflag, 1 ) )
312 : {
313 14 : y_gain4_fx[j + 1] = Comp_band_log_ener( pt_fx, 32, Q_exc, -1 ); /*Q12*/
314 14 : move16();
315 14 : pt_fx += 32;
316 : }
317 :
318 14 : return;
319 : }
320 :
321 207393 : void Ener_per_band_comp_ivas_fx(
322 : const Word16 exc_diff_fx[], /* i : target signal Q_exc_diff */
323 : Word16 y_gain4_fx[], /* o : Energy per band to quantize Q12 */
324 : const Word16 Q_exc, /* i : frame length */
325 : const Word16 Mband, /* i : Max band */
326 : const Word16 Eflag, /* i : flag of highest band */
327 : const Word16 L_frame /* i : frame length */
328 : )
329 : {
330 : const Word16 *pt_fx;
331 : Word16 j;
332 :
333 207393 : pt_fx = exc_diff_fx;
334 622179 : FOR( j = 0; j < 2; j++ )
335 : {
336 414786 : y_gain4_fx[j] = Comp_band_log_ener( pt_fx, 8, Q_exc, 1 ); /*Q12*/
337 414786 : move16();
338 414786 : pt_fx += 8;
339 : }
340 :
341 2903418 : FOR( j = 1; j < Mband - 2; j++ )
342 : {
343 2696025 : y_gain4_fx[j + 1] = Comp_band_log_ener( pt_fx, 16, Q_exc, 0 ); /*Q12*/
344 2696025 : move16();
345 2696025 : pt_fx += 16;
346 : }
347 :
348 207393 : IF( EQ_16( Eflag, 1 ) )
349 : {
350 207332 : y_gain4_fx[j + 1] = Comp_band_log_ener( pt_fx, 32, Q_exc, -1 ); /*Q12*/
351 207332 : move16();
352 207332 : pt_fx += 32;
353 : }
354 :
355 207393 : IF( EQ_16( L_frame, L_FRAME16k ) )
356 : {
357 75119 : y_gain4_fx[j + 2] = Comp_band_log_ener( pt_fx, 32, Q_exc, -1 ); /*Q12*/
358 75119 : move16();
359 75119 : y_gain4_fx[j + 3] = Comp_band_log_ener( pt_fx, 64, Q_exc, -1 ); /*Q12*/
360 75119 : move16();
361 75119 : pt_fx += 64;
362 : }
363 :
364 207393 : return;
365 : }
366 0 : void Ener_per_band_comp_ivas_fx_2(
367 : const Word16 exc_diff[], /* i : target signal Q_exc */
368 : Word16 y_gain4[], /* o : Energy per band to quantize Q12 */
369 : const Word16 Q_exc,
370 : const Word16 Mband, /* i : Max band */
371 : const Word16 Eflag, /* i : flag of highest band */
372 : const Word16 L_frame /* i : frame length */
373 : )
374 : {
375 : Word32 etmp, L_tmp;
376 : Word16 etmp_e;
377 : const Word16 *pt;
378 : Word16 i, j, tmp;
379 0 : tmp = add( shl( sub( Q15, Q_exc ), 1 ), 1 );
380 :
381 0 : pt = exc_diff;
382 0 : FOR( j = 0; j < 2; j++ )
383 : {
384 0 : y_gain4[j] = 0;
385 0 : move16();
386 0 : etmp = 42949673; /* 0.02 in Q31 */
387 0 : move32();
388 0 : etmp_e = 0;
389 0 : move16();
390 :
391 0 : pt = exc_diff + shl( j, 3 );
392 0 : FOR( i = 0; i < 8; i++ )
393 : {
394 0 : etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e );
395 0 : pt++;
396 : }
397 :
398 : /* normalized to 16 bins to easy the quantization */
399 0 : etmp_e = add( etmp_e, 1 );
400 0 : etmp = Sqrt32( etmp, &etmp_e );
401 0 : etmp = BASOP_Util_Log10( etmp, etmp_e ); // Q25
402 0 : y_gain4[j] = extract_h( L_shl( etmp, 3 ) ); // Q12
403 0 : move16();
404 : }
405 :
406 0 : FOR( j = 1; j < Mband - 2; j++ )
407 : {
408 0 : etmp = 21474836; /* 0.01 in Q31 */
409 0 : move32();
410 0 : etmp_e = 0;
411 0 : move16();
412 :
413 0 : pt = exc_diff + shl( j, 4 );
414 0 : FOR( i = 0; i < 16; i++ )
415 : {
416 0 : etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e );
417 0 : pt++;
418 : }
419 :
420 0 : etmp = Sqrt32( etmp, &etmp_e );
421 0 : etmp = BASOP_Util_Log10( etmp, etmp_e ); // Q25
422 0 : y_gain4[j + 1] = extract_h( L_shl( etmp, 3 ) ); // Q12
423 0 : move16();
424 : }
425 :
426 0 : IF( EQ_16( Eflag, 1 ) )
427 : {
428 0 : etmp = 21474836; /* 0.01 in Q31 */
429 0 : move32();
430 0 : etmp_e = 0;
431 0 : move16();
432 :
433 0 : pt = exc_diff + shl( j, 4 );
434 0 : FOR( i = 0; i < 32; i++ )
435 : {
436 0 : etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e );
437 0 : pt++;
438 : }
439 :
440 0 : etmp_e = sub( etmp_e, 1 );
441 0 : etmp = Sqrt32( etmp, &etmp_e );
442 0 : etmp = BASOP_Util_Log10( etmp, etmp_e ); // Q25
443 0 : y_gain4[j + 1] = extract_h( L_shl( etmp, 3 ) ); // Q12
444 0 : move16();
445 : }
446 :
447 0 : IF( EQ_16( L_frame, L_FRAME16k ) )
448 : {
449 0 : etmp = 21474836; /* 0.01 in Q31 */
450 0 : move32();
451 0 : etmp_e = 0;
452 0 : move16();
453 :
454 0 : FOR( i = 0; i < 32; i++ )
455 : {
456 0 : etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e );
457 0 : pt++;
458 : }
459 :
460 0 : Word16 tmp2 = sub( etmp_e, 1 );
461 0 : L_tmp = Sqrt32( etmp, &tmp2 );
462 0 : L_tmp = BASOP_Util_Log10( L_tmp, tmp2 ); // Q25
463 0 : y_gain4[j + 2] = extract_h( L_shl( L_tmp, 3 ) ); // Q12
464 0 : move16();
465 :
466 0 : FOR( i = 0; i < 32; i++ )
467 : {
468 0 : etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e );
469 0 : pt++;
470 : }
471 :
472 0 : etmp_e = sub( etmp_e, 1 );
473 0 : etmp = Sqrt32( etmp, &etmp_e );
474 0 : etmp = BASOP_Util_Log10( etmp, etmp_e ); // Q25
475 0 : y_gain4[j + 3] = extract_h( L_shl( etmp, 3 ) ); // Q12
476 0 : move16();
477 : }
478 :
479 0 : return;
480 : }
481 :
482 : /*-------------------------------------------------------------------*
483 : * gsc_gainQ()
484 : *
485 : * Quantization of the energy per band
486 : *-------------------------------------------------------------------*/
487 13 : static void GSC_gain_adj(
488 : const Word16 coder_type, /* i : Coder type */
489 : const Word32 core_brate, /* i : Bit rate */
490 : const Word16 mean_g, /* i : Average gain Q12 */
491 : Word16 *old_y_gain, /* i/o: Previous frame dequantized vector */
492 : const Word16 *y_gain_tmp, /* i : Dequantized gains */
493 : Word16 *y_gainQ /* i/o: Output gains Q12 */
494 : )
495 : {
496 : /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
497 : Word16 Gain_off, i;
498 :
499 13 : IF( coder_type != INACTIVE )
500 : {
501 0 : FOR( i = 0; i < MBANDS_GN; i++ )
502 : {
503 0 : old_y_gain[i] = y_gain_tmp[i];
504 0 : move16();
505 0 : y_gainQ[i] = add( y_gain_tmp[i], mean_g );
506 0 : move16();
507 : }
508 : }
509 : ELSE
510 : {
511 13 : Gain_off = 0;
512 13 : move16();
513 13 : IF( LE_32( core_brate, ACELP_7k20 ) )
514 : {
515 0 : Gain_off = 32767;
516 0 : move16(); /* 8 -> Q12 */
517 : }
518 13 : ELSE IF( LE_32( core_brate, ACELP_8k00 ) )
519 : {
520 0 : Gain_off = 27034;
521 0 : move16(); /* 6.6f -> Q12 */
522 : }
523 13 : ELSE IF( LE_32( core_brate, ACELP_9k60 ) )
524 : {
525 0 : Gain_off = 19661;
526 0 : move16(); /*4.8f-> Q12 */
527 : }
528 13 : ELSE IF( LE_32( core_brate, ACELP_11k60 ) )
529 : {
530 13 : Gain_off = 14336;
531 13 : move16(); /* 3.5f -> Q12 */
532 : }
533 0 : ELSE IF( LE_32( core_brate, ACELP_13k20 ) )
534 : {
535 0 : Gain_off = 12288;
536 0 : move16(); /* 3.0f -> Q12 dB */
537 : }
538 :
539 : /*mimic ACELP decay of energy for low rates*/
540 221 : FOR( i = 0; i < MBANDS_GN; i++ )
541 : {
542 208 : old_y_gain[i] = y_gain_tmp[i];
543 208 : move16();
544 : /*y_gainQ[i] = y_gain_tmp[i]+mean_4g[0]-(i*(Gain_off/20.f)/((float) Mbands_gn));*/
545 208 : y_gainQ[i] = add( y_gain_tmp[i], sub( mean_g, i_mult2( i, mult_r( Gain_off, 102 /* 20/MBANDS_GN in Q15 */ ) ) ) );
546 208 : move16();
547 : }
548 : }
549 :
550 13 : return;
551 : }
552 :
553 : /*-------------------------------------------------------------------*
554 : * GSC_gain_adj_ivas_fx()
555 : *
556 : * Quantization of the energy per band
557 : *-------------------------------------------------------------------*/
558 20554 : static void GSC_gain_adj_ivas_fx(
559 : const Word16 coder_type, /* i : Coder type */
560 : const Word16 Mbands_gn, /* i : Number of band */
561 : const Word32 core_brate, /* i : Bit rate */
562 : const Word16 mean_g, /* i : Average gain Q12 */
563 : Word16 *old_y_gain, /* i/o: Previous frame dequantized vector */
564 : const Word16 *y_gain_tmp, /* i : Dequantized gains */
565 : Word16 *y_gainQ /* i/o: Output gains Q12 */
566 : )
567 : {
568 : /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
569 : Word16 Gain_off, i;
570 :
571 20554 : test();
572 20554 : IF( ( coder_type != INACTIVE ) && NE_16( coder_type, UNVOICED ) )
573 : {
574 166141 : FOR( i = 0; i < Mbands_gn; i++ )
575 : {
576 156368 : old_y_gain[i] = y_gain_tmp[i];
577 156368 : move16();
578 156368 : y_gainQ[i] = add( y_gain_tmp[i], mean_g );
579 156368 : move16();
580 : }
581 : }
582 : ELSE
583 : {
584 10781 : Gain_off = 0;
585 10781 : move16();
586 :
587 10781 : test();
588 10781 : IF( LE_32( core_brate, ACELP_5k00 ) && EQ_16( coder_type, UNVOICED ) )
589 : {
590 8 : Gain_off = 18432;
591 8 : move16(); /* 9 -> Q11 */
592 : }
593 10781 : IF( LE_32( core_brate, ACELP_7k20 ) )
594 : {
595 6719 : Gain_off = 16384;
596 6719 : move16(); /* 8 -> Q11 */
597 : }
598 4062 : ELSE IF( LE_32( core_brate, ACELP_8k00 ) )
599 : {
600 13 : Gain_off = 13517;
601 13 : move16(); /* 6.6f -> Q11 */
602 : }
603 4049 : ELSE IF( LE_32( core_brate, ACELP_9k60 ) )
604 : {
605 354 : Gain_off = 9830;
606 354 : move16(); /*4.8f-> Q11 */
607 : }
608 3695 : ELSE IF( LE_32( core_brate, ACELP_11k60 ) )
609 : {
610 154 : Gain_off = 7168;
611 154 : move16(); /* 3.5f -> Q11 */
612 : }
613 3541 : ELSE IF( LE_32( core_brate, ACELP_13k20 ) )
614 : {
615 380 : Gain_off = 6144;
616 380 : move16(); /* 3.0f -> Q11 dB */
617 : }
618 :
619 : /*mimic ACELP decay of energy for low rates*/
620 188327 : FOR( i = 0; i < Mbands_gn; i++ )
621 : {
622 177546 : old_y_gain[i] = y_gain_tmp[i];
623 177546 : move16();
624 177546 : y_gainQ[i] = add( y_gain_tmp[i], sub( mean_g, i_mult2( i, mult_r( Gain_off, 205 /* 20/MBANDS_GN in Q16 */ ) ) ) );
625 177546 : move16();
626 : }
627 : }
628 :
629 20554 : return;
630 : }
631 :
632 : /*==========================================================================*/
633 : /* FUNCTION : Word16 gsc_gaindec_fx () */
634 : /*--------------------------------------------------------------------------*/
635 : /* PURPOSE : Generic signal frequency band decoding and application */
636 : /*--------------------------------------------------------------------------*/
637 : /* INPUT ARGUMENTS : */
638 : /* _ (Word16) pvq_bits_fx : core used Q0 */
639 : /* _ (Word16) coder_type : coding type Q0 */
640 : /* _ (Word16) core_fx : core used Q0 */
641 : /* _ (Word16) bwidth_fx : input signal bandwidth Q0 */
642 : /*--------------------------------------------------------------------------*/
643 : /* OUTPUT ARGUMENTS : */
644 : /* _ (Word16[]) y_gainQ_fx : quantized gain per band */
645 : /*--------------------------------------------------------------------------*/
646 : /* INPUT/OUTPUT ARGUMENTS : */
647 : /* _ (Word16[]) old_y_gain_fx : AR gain quantizer for low rate */
648 : /*--------------------------------------------------------------------------*/
649 : /* RETURN ARGUMENTS : */
650 : /* _ (Word16) : average frequency gain */
651 : /*==========================================================================*/
652 6 : Word16 gsc_gaindec_fx( /* o : average frequency gain */
653 : Decoder_State *st_fx, /* i/o: decoder state structure */
654 : Word16 y_gainQ_fx[], /* o : quantized gain per band */
655 : const Word32 core_brate_fx, /* i : core used */
656 : Word16 old_y_gain_fx[], /* i/o: AR gain quantizer for low rate */
657 : const Word16 coder_type, /* i : coding type */
658 : const Word16 bwidth_fx /* i : input signal bandwidth */
659 : )
660 : {
661 : Word16 idx_g_fx, i;
662 : Word16 mean_4g_fx;
663 : Word16 y_gain_tmp3_fx[MBANDS_GN];
664 :
665 6 : test();
666 6 : test();
667 6 : IF( ( EQ_16( coder_type, AUDIO ) || ( coder_type == INACTIVE ) ) && EQ_16( bwidth_fx, NB ) )
668 : {
669 0 : idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 6 ) );
670 0 : VDQ_vec_fx( &mean_4g_fx, Gain_meanNB_fx, Gain_mean_dicNB_fx, idx_g_fx, 1 );
671 :
672 0 : idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 6 ) );
673 0 : VDQ_vec_fx( y_gainQ_fx, Mean_dic_NB_fx, Gain_dic1_NB_fx, idx_g_fx, 3 );
674 :
675 0 : IF( LT_32( core_brate_fx, ACELP_9k60 ) )
676 : {
677 0 : idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 5 ) );
678 0 : VDQ_vec_fx( y_gainQ_fx + 3, Mean_dic_NB_fx + 3, Gain_dic2_NB_fx, idx_g_fx, 3 );
679 :
680 0 : idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 4 ) );
681 0 : VDQ_vec_fx( y_gainQ_fx + 6, Mean_dic_NB_fx + 6, Gain_dic3_NB_fx, idx_g_fx, 4 );
682 : }
683 : ELSE
684 : {
685 0 : idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 6 ) );
686 0 : VDQ_vec_fx( y_gainQ_fx + 3, Mean_dic_NB_fx + 3, Gain_dic2_NBHR_fx, idx_g_fx, 3 );
687 :
688 0 : idx_g_fx = (Word16) ( get_next_indice_fx( st_fx, 7 ) );
689 0 : VDQ_vec_fx( y_gainQ_fx + 6, Mean_dic_NB_fx + 6, Gain_dic3_NBHR_fx, idx_g_fx, 4 );
690 : }
691 0 : test();
692 0 : IF( LE_32( core_brate_fx, ACELP_9k60 ) && ( coder_type == INACTIVE ) )
693 : {
694 : /* Some energy is needed in high band for stat_noise_uv_enc
695 : to be functional in inactive speech */
696 0 : y_gainQ_fx[10] = mean_fx( y_gainQ_fx + 6, 3 );
697 0 : move16();
698 0 : y_gainQ_fx[11] = mean_fx( y_gainQ_fx + 7, 3 );
699 0 : move16();
700 0 : y_gainQ_fx[12] = mean_fx( y_gainQ_fx + 8, 3 );
701 0 : move16();
702 0 : y_gainQ_fx[13] = mean_fx( y_gainQ_fx + 9, 3 );
703 0 : move16();
704 0 : y_gainQ_fx[14] = mean_fx( y_gainQ_fx + 10, 3 );
705 0 : move16();
706 0 : y_gainQ_fx[15] = mean_fx( y_gainQ_fx + 11, 3 );
707 0 : move16();
708 : }
709 : ELSE
710 : {
711 0 : set16_fx( y_gainQ_fx + 10, 0, MBANDS_GN - 10 );
712 : }
713 : }
714 : ELSE
715 : {
716 6 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
717 :
718 6 : VDQ_vec_fx( &mean_4g_fx, mean_m_fx, mean_gain_dic_fx, idx_g_fx, 1 );
719 :
720 6 : IF( LE_32( core_brate_fx, ACELP_9k60 ) )
721 : {
722 : /*--------------------------------------------------------------------------------------*
723 : * UQ of the first 8 bands and half of the last 8 bands
724 : *--------------------------------------------------------------------------------------*/
725 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
726 0 : VDQ_vec_fx( y_gainQ_fx, YGain_mean_LR_fx, YGain_dic1_LR_fx, idx_g_fx, 3 );
727 :
728 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
729 0 : VDQ_vec_fx( y_gainQ_fx + 3, YGain_mean_LR_fx + 3, YGain_dic2_LR_fx, idx_g_fx, 4 );
730 :
731 : /*----------------------------------------------------------------------*
732 : * Interpolation of the last 4 Q bands to create bands 8-16
733 : * And scaling
734 : *----------------------------------------------------------------------*/
735 :
736 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
737 :
738 0 : VDQ_vec_fx( y_gainQ_fx + 7, YGain_mean_LR_fx + 7, YGain_dic3_LR_fx, idx_g_fx, 5 );
739 :
740 0 : Copy( y_gainQ_fx + 8, y_gain_tmp3_fx, 4 );
741 0 : set16_fx( y_gainQ_fx + 12, 0, 4 );
742 :
743 0 : fft_rel_fx( y_gainQ_fx + 8, 4, 2 );
744 :
745 0 : y_gainQ_fx[15] = y_gainQ_fx[11];
746 0 : move16();
747 0 : y_gainQ_fx[11] = 0;
748 0 : move16();
749 0 : ifft_rel_fx( y_gainQ_fx + 8, 8, 3 );
750 0 : FOR( i = 8; i < 16; i++ )
751 : {
752 0 : y_gainQ_fx[i] = round_fx( L_shl( L_mult( y_gainQ_fx[i], 23101 ), 1 ) ); /*Q12 */
753 0 : move16();
754 : }
755 : /*----------------------------------------------------------------------*
756 : * Copy the true Q values in the specific bands
757 : *----------------------------------------------------------------------*/
758 0 : y_gainQ_fx[8] = y_gain_tmp3_fx[0];
759 0 : move16();
760 0 : y_gainQ_fx[10] = y_gain_tmp3_fx[1];
761 0 : move16();
762 0 : y_gainQ_fx[12] = y_gain_tmp3_fx[2];
763 0 : move16();
764 0 : y_gainQ_fx[14] = y_gain_tmp3_fx[3];
765 0 : move16();
766 : }
767 : ELSE
768 : {
769 6 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
770 6 : VDQ_vec_fx( y_gainQ_fx, YG_mean16_fx, YG_dicMR_1_fx, idx_g_fx, 4 );
771 :
772 6 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
773 6 : VDQ_vec_fx( y_gainQ_fx + 4, YG_mean16_fx + 4, YG_dicMR_2_fx, idx_g_fx, 4 );
774 :
775 6 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
776 6 : VDQ_vec_fx( y_gainQ_fx + 8, YG_mean16_fx + 8, YG_dicMR_3_fx, idx_g_fx, 4 );
777 :
778 6 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 4 );
779 6 : VDQ_vec_fx( y_gainQ_fx + 12, YG_mean16_fx + 12, YG_dicMR_4_fx, idx_g_fx, 4 );
780 : }
781 : }
782 :
783 : /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
784 6 : GSC_gain_adj( coder_type, core_brate_fx, mean_4g_fx, old_y_gain_fx, y_gainQ_fx, y_gainQ_fx );
785 :
786 6 : return mean_4g_fx;
787 : }
788 :
789 : /*==========================================================================*/
790 : /* FUNCTION : Word16 gsc_gaindec_ivas_fx () */
791 : /*--------------------------------------------------------------------------*/
792 : /* PURPOSE : Generic signal frequency band decoding and application */
793 : /*--------------------------------------------------------------------------*/
794 : /* INPUT ARGUMENTS : */
795 : /* _ (Word16) pvq_bits_fx : core used Q0 */
796 : /* _ (Word16) coder_type : coding type Q0 */
797 : /* _ (Word16) core_fx : core used Q0 */
798 : /* _ (Word16) bwidth_fx : input signal bandwidth Q0 */
799 : /*--------------------------------------------------------------------------*/
800 : /* OUTPUT ARGUMENTS : */
801 : /* _ (Word16[]) y_gainQ_fx : quantized gain per band */
802 : /*--------------------------------------------------------------------------*/
803 : /* INPUT/OUTPUT ARGUMENTS : */
804 : /* _ (Word16[]) old_y_gain_fx : AR gain quantizer for low rate */
805 : /*--------------------------------------------------------------------------*/
806 : /* RETURN ARGUMENTS : */
807 : /* _ (Word16) : average frequency gain */
808 : /*==========================================================================*/
809 20554 : Word16 gsc_gaindec_ivas_fx( /* o : average frequency gain */
810 : Decoder_State *st_fx, /* i/o: decoder state structure */
811 : Word16 y_gainQ_fx[], /* o : quantized gain per band Q12 */
812 : const Word32 core_brate_fx, /* i : core used */
813 : Word16 old_y_gain_fx[], /* i/o: AR gain quantizer for low rate */
814 : const Word16 coder_type, /* i : coding type */
815 : const Word16 bwidth_fx /* i : input signal bandwidth */
816 : )
817 : {
818 : Word16 idx_g_fx, i;
819 : Word16 mean_4g_fx;
820 20554 : Word16 Mbands_gn = MBANDS_GN;
821 20554 : move16();
822 : Word16 y_gain_tmp3_fx[MBANDS_GN];
823 20554 : if ( EQ_16( st_fx->L_frame, L_FRAME16k ) )
824 : {
825 2525 : Mbands_gn = MBANDS_GN16k;
826 2525 : move16();
827 : }
828 :
829 20554 : test();
830 20554 : test();
831 20554 : IF( ( EQ_16( coder_type, AUDIO ) || ( coder_type == INACTIVE ) ) && EQ_16( bwidth_fx, NB ) )
832 : {
833 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
834 0 : VDQ_vec_fx( &mean_4g_fx, Gain_meanNB_fx, Gain_mean_dicNB_fx, idx_g_fx, 1 );
835 :
836 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
837 0 : VDQ_vec_fx( y_gainQ_fx, Mean_dic_NB_fx, Gain_dic1_NB_fx, idx_g_fx, 3 );
838 :
839 0 : IF( LT_32( core_brate_fx, ACELP_9k60 ) )
840 : {
841 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
842 0 : VDQ_vec_fx( y_gainQ_fx + 3, Mean_dic_NB_fx + 3, Gain_dic2_NB_fx, idx_g_fx, 3 );
843 :
844 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 4 );
845 0 : VDQ_vec_fx( y_gainQ_fx + 6, Mean_dic_NB_fx + 6, Gain_dic3_NB_fx, idx_g_fx, 4 );
846 : }
847 : ELSE
848 : {
849 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
850 0 : VDQ_vec_fx( y_gainQ_fx + 3, Mean_dic_NB_fx + 3, Gain_dic2_NBHR_fx, idx_g_fx, 3 );
851 :
852 0 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 7 );
853 0 : VDQ_vec_fx( y_gainQ_fx + 6, Mean_dic_NB_fx + 6, Gain_dic3_NBHR_fx, idx_g_fx, 4 );
854 : }
855 0 : test();
856 0 : IF( LE_32( core_brate_fx, ACELP_9k60 ) && ( coder_type == INACTIVE ) )
857 : {
858 : /* Some energy is needed in high band for stat_noise_uv_enc
859 : to be functional in inactive speech */
860 0 : y_gainQ_fx[10] = mean_fx( y_gainQ_fx + 6, 3 ); /*Q12*/
861 0 : move16();
862 0 : y_gainQ_fx[11] = mean_fx( y_gainQ_fx + 7, 3 ); /*Q12*/
863 0 : move16();
864 0 : y_gainQ_fx[12] = mean_fx( y_gainQ_fx + 8, 3 ); /*Q12*/
865 0 : move16();
866 0 : y_gainQ_fx[13] = mean_fx( y_gainQ_fx + 9, 3 ); /*Q12*/
867 0 : move16();
868 0 : y_gainQ_fx[14] = mean_fx( y_gainQ_fx + 10, 3 ); /*Q12*/
869 0 : move16();
870 0 : y_gainQ_fx[15] = mean_fx( y_gainQ_fx + 11, 3 ); /*Q12*/
871 0 : move16();
872 : }
873 : ELSE
874 : {
875 0 : set16_fx( y_gainQ_fx + 10, 0, MBANDS_GN - 10 );
876 : }
877 : }
878 : ELSE
879 : {
880 20554 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
881 :
882 20554 : VDQ_vec_fx( &mean_4g_fx, mean_m_fx, mean_gain_dic_fx, idx_g_fx, 1 );
883 :
884 20554 : IF( LT_32( core_brate_fx, ACELP_9k60 ) )
885 : {
886 : /*--------------------------------------------------------------------------------------*
887 : * UQ of the first 8 bands and half of the last 8 bands
888 : *--------------------------------------------------------------------------------------*/
889 13136 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
890 13136 : VDQ_vec_fx( y_gainQ_fx, YGain_mean_LR_fx, YGain_dic1_LR_fx, idx_g_fx, 3 );
891 :
892 13136 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
893 13136 : VDQ_vec_fx( y_gainQ_fx + 3, YGain_mean_LR_fx + 3, YGain_dic2_LR_fx, idx_g_fx, 4 );
894 :
895 : /*----------------------------------------------------------------------*
896 : * Interpolation of the last 4 Q bands to create bands 8-16
897 : * And scaling
898 : *----------------------------------------------------------------------*/
899 :
900 13136 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
901 :
902 13136 : VDQ_vec_fx( y_gainQ_fx + 7, YGain_mean_LR_fx + 7, YGain_dic3_LR_fx, idx_g_fx, 5 );
903 :
904 13136 : Copy( y_gainQ_fx + 8, y_gain_tmp3_fx, 4 );
905 13136 : set16_fx( y_gainQ_fx + 12, 0, 4 );
906 :
907 13136 : fft_rel_fx( y_gainQ_fx + 8, 4, 2 );
908 :
909 13136 : y_gainQ_fx[15] = y_gainQ_fx[11];
910 13136 : move16();
911 13136 : y_gainQ_fx[11] = 0;
912 13136 : move16();
913 13136 : ifft_rel_fx( y_gainQ_fx + 8, 8, 3 );
914 118224 : FOR( i = 8; i < 16; i++ )
915 : {
916 105088 : y_gainQ_fx[i] = round_fx( L_shl( L_mult( y_gainQ_fx[i], 23101 ), 1 ) ); /*Q12 */
917 105088 : move16();
918 : }
919 : /*----------------------------------------------------------------------*
920 : * Copy the true Q values in the specific bands
921 : *----------------------------------------------------------------------*/
922 13136 : y_gainQ_fx[8] = y_gain_tmp3_fx[0]; /*Q12*/
923 13136 : move16();
924 13136 : y_gainQ_fx[10] = y_gain_tmp3_fx[1]; /*Q12*/
925 13136 : move16();
926 13136 : y_gainQ_fx[12] = y_gain_tmp3_fx[2]; /*Q12*/
927 13136 : move16();
928 13136 : y_gainQ_fx[14] = y_gain_tmp3_fx[3]; /*Q12*/
929 13136 : move16();
930 : }
931 : ELSE
932 : {
933 7418 : IF( EQ_16( st_fx->L_frame, L_FRAME ) )
934 : {
935 4893 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
936 4893 : VDQ_vec_fx( y_gainQ_fx, YG_mean16_fx, YG_dicMR_1_fx, idx_g_fx, 4 );
937 :
938 4893 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
939 4893 : VDQ_vec_fx( y_gainQ_fx + 4, YG_mean16_fx + 4, YG_dicMR_2_fx, idx_g_fx, 4 );
940 :
941 4893 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 5 );
942 4893 : VDQ_vec_fx( y_gainQ_fx + 8, YG_mean16_fx + 8, YG_dicMR_3_fx, idx_g_fx, 4 );
943 :
944 4893 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 4 );
945 4893 : VDQ_vec_fx( y_gainQ_fx + 12, YG_mean16_fx + 12, YG_dicMR_4_fx, idx_g_fx, 4 );
946 : }
947 : ELSE
948 : {
949 2525 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 7 );
950 2525 : VDQ_vec_fx( y_gainQ_fx, YG_mean16HR_fx, YG_dicHR_1_fx, idx_g_fx, 4 );
951 :
952 2525 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
953 2525 : VDQ_vec_fx( y_gainQ_fx + 4, YG_mean16HR_fx + 4, YG_dicHR_2_fx, idx_g_fx, 4 );
954 :
955 2525 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
956 2525 : VDQ_vec_fx( y_gainQ_fx + 8, YG_mean16HR_fx + 8, YG_dicHR_3_fx, idx_g_fx, 4 );
957 :
958 2525 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 6 );
959 2525 : VDQ_vec_fx( y_gainQ_fx + 12, YG_mean16HR_16kHz_fx, YG_dicHR_4_16kHz_fx, idx_g_fx, 4 );
960 :
961 2525 : idx_g_fx = (Word16) get_next_indice_fx( st_fx, 3 );
962 2525 : VDQ_vec_fx( y_gainQ_fx + 16, YG_meanL2G_16kHz_fx, YG_dicL2G_16kHz_fx, idx_g_fx, 2 );
963 : }
964 : }
965 : }
966 :
967 : /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
968 20554 : GSC_gain_adj_ivas_fx( coder_type, Mbands_gn, core_brate_fx, mean_4g_fx, old_y_gain_fx, y_gainQ_fx, y_gainQ_fx );
969 :
970 20554 : return mean_4g_fx;
971 : }
972 :
973 : /*-------------------------------------------------------------------*
974 : * gsc_gainQ()
975 : *
976 : * Quantization of the energy per band
977 : *-------------------------------------------------------------------*/
978 7 : Word16 gsc_gainQ_fx( /*Q12*/
979 : BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */
980 : const Word16 y_gain4[], /* i : Energy per band Q12 */
981 : Word16 y_gainQ[], /* o : quantized energy per band Q12 */
982 : const Word32 core_brate, /* i : Core rate */
983 : const Word16 coder_type, /* i : coding type */
984 : const Word16 bwidth /* i : input signal bandwidth */
985 : )
986 : {
987 : Word16 y_gain_tmp[MBANDS_GN], y_gain_tmp2[MBANDS_GN];
988 7 : Word16 i, idx_g = 0;
989 7 : move16();
990 7 : Word16 mean_4g[1] = { 0 }, tmp16, tmp1, tmp2;
991 7 : move16();
992 7 : Word16 Mbands_gn = MBANDS_GN;
993 : Word16 y_gain_tmp3[MBANDS_GN];
994 : Word16 cnt;
995 : Word32 L_tmp;
996 :
997 7 : mean_4g[0] = 0;
998 :
999 7 : test();
1000 7 : test();
1001 7 : IF( ( EQ_16( coder_type, AUDIO ) || ( coder_type == INACTIVE ) ) && ( bwidth == NB ) )
1002 : {
1003 :
1004 : /*ftmp1 = mean(y_gain4, 10)-0.6f;*/
1005 0 : L_tmp = L_deposit_l( 0 );
1006 0 : FOR( cnt = 0; cnt < 10; cnt++ )
1007 : {
1008 0 : L_tmp = L_mac( L_tmp, y_gain4[cnt], 3277 /*0.1 in Q15*/ );
1009 : }
1010 0 : tmp16 = sub( round_fx( L_tmp ), 4915 );
1011 :
1012 0 : FOR( i = 0; i < Mbands_gn; i++ )
1013 : {
1014 0 : y_gain_tmp2[i] = y_gain4[i];
1015 0 : move16();
1016 : /*if(y_gain4[i] < ftmp1-0.6f)*/
1017 0 : y_gain_tmp2[i] = s_max( y_gain_tmp2[i], tmp16 );
1018 0 : move16();
1019 : }
1020 :
1021 0 : L_tmp = L_deposit_l( 0 );
1022 0 : FOR( i = 0; i < 10; i++ )
1023 : {
1024 0 : L_tmp = L_mac( L_tmp, y_gain_tmp2[i], 3277 /*0.1 in Q15*/ );
1025 : }
1026 :
1027 : /* Quantized mean gain without clipping */
1028 0 : mean_4g[0] = round_fx( L_tmp );
1029 0 : move16();
1030 0 : idx_g = vquant_fx( mean_4g, Gain_meanNB_fx, mean_4g, Gain_mean_dicNB_fx, 1, 64 );
1031 0 : push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
1032 :
1033 0 : FOR( i = 0; i < Mbands_gn; i++ )
1034 : {
1035 0 : y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g[0] );
1036 0 : move16();
1037 : }
1038 : /*if(y_gain_tmp[9] < -0.3f){y_gain_tmp[9] = -0.3f;}*/
1039 0 : y_gain_tmp[9] = s_max( y_gain_tmp[9], -1229 /*0.3 in Q12*/ );
1040 0 : move16();
1041 0 : set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
1042 0 : idx_g = vquant_fx( y_gain_tmp, Mean_dic_NB_fx, y_gain_tmp, Gain_dic1_NB_fx, 3, 64 );
1043 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
1044 :
1045 0 : IF( LT_32( core_brate, ACELP_9k60 ) )
1046 : {
1047 0 : idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NB_fx, 3, 32 );
1048 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
1049 0 : idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NB_fx, 4, 16 );
1050 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
1051 : }
1052 : ELSE
1053 : {
1054 0 : idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NBHR_fx, 3, 64 );
1055 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
1056 0 : idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NBHR_fx, 4, 128 );
1057 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 );
1058 : } /*add end */
1059 :
1060 0 : test();
1061 0 : IF( LE_32( core_brate, ACELP_9k60 ) && ( coder_type == INACTIVE ) )
1062 : {
1063 : /* Some energy is needed in high band for stat_noise_uv_enc
1064 : to be functional in inactive speech */
1065 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 ) );
1066 0 : move16();
1067 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 ) );
1068 0 : move16();
1069 :
1070 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 ) );
1071 0 : move16();
1072 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 ) );
1073 0 : move16();
1074 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 ) );
1075 0 : move16();
1076 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 ) );
1077 0 : move16();
1078 : }
1079 : ELSE
1080 : {
1081 0 : set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
1082 : }
1083 : }
1084 : ELSE
1085 : {
1086 : /*ftmp1 = mean(y_gain4, 16);*/
1087 :
1088 7 : L_tmp = 0;
1089 7 : move32();
1090 119 : FOR( cnt = 0; cnt < 16; cnt++ )
1091 : {
1092 112 : L_tmp = L_mac( L_tmp, y_gain4[cnt], 2048 );
1093 : }
1094 7 : tmp16 = round_fx( L_tmp );
1095 :
1096 7 : tmp1 = sub( tmp16, 4915 );
1097 7 : tmp2 = add( tmp16, 4915 );
1098 7 : L_tmp = 0;
1099 7 : move32();
1100 119 : FOR( i = 0; i < 16; i++ )
1101 : {
1102 112 : y_gain_tmp2[i] = y_gain4[i];
1103 112 : move16();
1104 112 : y_gain_tmp2[i] = s_max( y_gain_tmp2[i], tmp1 );
1105 112 : move16();
1106 112 : y_gain_tmp2[i] = s_min( y_gain_tmp2[i], tmp2 );
1107 112 : move16();
1108 112 : L_tmp = L_mac( L_tmp, y_gain_tmp2[i], 2048 );
1109 : }
1110 7 : FOR( ; i < Mbands_gn; i++ )
1111 : {
1112 0 : y_gain_tmp2[i] = y_gain4[i];
1113 0 : move16();
1114 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*/
1115 0 : move16();
1116 0 : y_gain_tmp2[i] = s_min( y_gain_tmp2[i], tmp2 );
1117 0 : move16();
1118 : }
1119 :
1120 : /* Quantized mean gain without clipping */
1121 7 : mean_4g[0] = round_fx( L_tmp );
1122 7 : move16();
1123 :
1124 7 : idx_g = vquant_fx( mean_4g, mean_m_fx, mean_4g, mean_gain_dic_fx, 1, 64 );
1125 7 : push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
1126 :
1127 119 : FOR( i = 0; i < Mbands_gn; i++ )
1128 : {
1129 112 : y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g[0] );
1130 112 : move16();
1131 : }
1132 :
1133 7 : IF( LT_32( core_brate, ACELP_9k60 ) )
1134 : {
1135 : /*mvr2r(y_gain_tmp, y_gain_tmp2, 8); */
1136 0 : Copy( y_gain_tmp, y_gain_tmp2, 8 );
1137 :
1138 0 : y_gain_tmp2[8] = y_gain_tmp[8];
1139 0 : move16();
1140 0 : y_gain_tmp2[9] = y_gain_tmp[10];
1141 0 : move16();
1142 0 : y_gain_tmp2[10] = y_gain_tmp[12];
1143 0 : move16();
1144 0 : y_gain_tmp2[11] = y_gain_tmp[14];
1145 0 : move16();
1146 :
1147 0 : idx_g = 0;
1148 0 : move16();
1149 :
1150 0 : idx_g = vquant_fx( y_gain_tmp2, YGain_mean_LR_fx, y_gain_tmp2, YGain_dic1_LR_fx, 3, 32 );
1151 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
1152 0 : idx_g = vquant_fx( y_gain_tmp2 + 3, YGain_mean_LR_fx + 3, y_gain_tmp2 + 3, YGain_dic2_LR_fx, 4, 32 );
1153 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
1154 0 : idx_g = vquant_fx( y_gain_tmp2 + 7, YGain_mean_LR_fx + 7, y_gain_tmp2 + 7, YGain_dic3_LR_fx, 5, 32 );
1155 0 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
1156 0 : set16_fx( y_gain_tmp2 + 12, 0, MBANDS_GN - 12 );
1157 :
1158 : /* Update to quantized vector */
1159 0 : Copy( y_gain_tmp2, y_gain_tmp, 8 );
1160 :
1161 0 : Copy( y_gain_tmp2 + 8, y_gain_tmp3, 4 );
1162 0 : set16_fx( y_gain_tmp + 8, 0, 8 );
1163 0 : fft_rel_fx( y_gain_tmp2 + 8, 4, 2 );
1164 :
1165 0 : Copy( y_gain_tmp2 + 8, y_gain_tmp + 8, 3 );
1166 0 : y_gain_tmp[15] = y_gain_tmp2[11];
1167 0 : move16();
1168 0 : ifft_rel_fx( y_gain_tmp + 8, 8, 3 );
1169 :
1170 0 : FOR( i = 8; i < 16; i++ )
1171 : {
1172 0 : y_gain_tmp[i] = shl( mult_r( y_gain_tmp[i], 23101 ), 1 );
1173 0 : move16();
1174 : }
1175 :
1176 0 : y_gain_tmp[8] = y_gain_tmp3[0];
1177 0 : move16();
1178 0 : y_gain_tmp[10] = y_gain_tmp3[1];
1179 0 : move16();
1180 0 : y_gain_tmp[12] = y_gain_tmp3[2];
1181 0 : move16();
1182 0 : y_gain_tmp[14] = y_gain_tmp3[3];
1183 0 : move16();
1184 : }
1185 : ELSE
1186 : {
1187 7 : idx_g = vquant_fx( y_gain_tmp, YG_mean16_fx, y_gain_tmp, YG_dicMR_1_fx, 4, 64 );
1188 7 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
1189 7 : idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16_fx + 4, y_gain_tmp + 4, YG_dicMR_2_fx, 4, 32 );
1190 7 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
1191 7 : idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16_fx + 8, y_gain_tmp + 8, YG_dicMR_3_fx, 4, 32 );
1192 7 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
1193 7 : idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16_fx + 12, y_gain_tmp + 12, YG_dicMR_4_fx, 4, 16 );
1194 7 : push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
1195 : }
1196 : }
1197 :
1198 : /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
1199 7 : GSC_gain_adj( coder_type, core_brate, mean_4g[0], y_gain_tmp2 /* dummy buffer */, y_gain_tmp, y_gainQ );
1200 :
1201 7 : return mean_4g[0]; /*Q12*/
1202 : }
1203 : /*-------------------------------------------------------------------*
1204 : * VDQ_vec()
1205 : *
1206 : * Return the dequantized vector of index
1207 : *-------------------------------------------------------------------*/
1208 92189 : static Word16 VDQ_vec_fx(
1209 : Word16 *Qvec_out_fx, /* o: Quanitzed vector */
1210 : const Word16 *mean_dic_fx, /* i: average codebook */
1211 : const Word16 *dic_fx, /* i: codebook */
1212 : const Word16 index_fx, /* i: index of codebook*/
1213 : const Word16 vec_en_fx /* i: vector length */
1214 : )
1215 : {
1216 : Word16 i, j;
1217 :
1218 : /*j = shr_r(extract_l(L_mult(index_fx,vec_en_fx)),1);*/
1219 92189 : j = i_mult2( index_fx, vec_en_fx );
1220 394215 : FOR( i = 0; i < vec_en_fx; i++ )
1221 : {
1222 302026 : Qvec_out_fx[i] = dic_fx[j++];
1223 302026 : move16();
1224 : }
1225 :
1226 394215 : FOR( i = 0; i < vec_en_fx; i++ )
1227 : {
1228 302026 : Qvec_out_fx[i] = add( Qvec_out_fx[i], mean_dic_fx[i] );
1229 302026 : move16();
1230 : }
1231 :
1232 92189 : return index_fx;
1233 : }
|