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 : #include <stdint.h>
35 : #include "options.h"
36 : #include "cnst.h" /* Audio core constants */
37 : #include "rom_com.h" /* Static table prototypes */
38 : #include "prot_fx.h"
39 :
40 : /*--------------------------------------------------------------------------*
41 : * mdct_spectrum_denorm()
42 : *
43 : *
44 : *--------------------------------------------------------------------------*/
45 :
46 32 : void mdct_spectrum_denorm_fx(
47 : const Word16 inp_vector[], /* i : Q0 : */
48 : Word32 L_y2[], /* i/o : Qs : decoded spectrum */
49 : const Word16 band_start[], /* i : Q0 : table of start freq for every subband */
50 : const Word16 band_end[], /* i : Q0 : table of end freq for every subband */
51 : const Word16 band_width[], /* i : Q0 : table of bandwidth for every subband */
52 : const Word32 L_band_energy[], /* i : Qbe : band energy */
53 : const Word16 npulses[], /* i : Q0 : number of coded spectrum */
54 : const Word16 bands, /* i : Q0 : number of subbands */
55 : const Word16 ld_slope_fx, /* i : Q15 : */
56 : const Word16 pd_thresh_fx /* i : Q15 : */
57 : )
58 : {
59 : Word16 i, k;
60 : Word32 L_Eyy;
61 : Word32 L_tmp, L_temp;
62 : Word16 temp_fx, temp_lo_fx, temp_hi_fx;
63 : Word32 L_inp_tmp[L_FRAME48k];
64 : Word16 exp_norm;
65 : Word16 exp_safe;
66 : Word16 exp_normn, exp_normd;
67 :
68 : Word16 pd_fx;
69 : Word16 Qpd;
70 :
71 : Word16 div_pd_fx;
72 : Word16 Qdivpd;
73 : Word32 L_div_pd;
74 :
75 : Word16 frac, exp;
76 :
77 : Word16 gain_tweak_fx;
78 : Word16 Qtweak;
79 :
80 : Word16 exp_shift;
81 :
82 : Word16 QEyy;
83 : Word16 pow_fx;
84 : Word16 Qpow;
85 : Word16 Qdiv;
86 : Word16 Qgamma;
87 : Word16 gamma_fx;
88 :
89 : Word16 cond_fx;
90 :
91 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
92 32 : Flag Overflow = 0;
93 32 : move16(); /* allow overflow happen. */
94 : #endif
95 :
96 32 : exp_safe = 4; /* safe bit for overflow */
97 32 : move16();
98 :
99 756 : FOR( k = 0; k < bands; k++ )
100 : {
101 724 : L_tmp = L_deposit_l( 0 );
102 18900 : FOR( i = band_start[k]; i <= band_end[k]; i++ )
103 : {
104 18176 : L_inp_tmp[i] = L_mult( inp_vector[i], inp_vector[i] );
105 18176 : move32(); /* Q0+Q0+1 */
106 18176 : L_tmp = L_or( L_tmp, L_inp_tmp[i] );
107 : }
108 724 : exp_norm = norm_l( L_tmp );
109 724 : exp_norm = sub( exp_norm, exp_safe );
110 :
111 724 : L_Eyy = L_deposit_l( 0 );
112 18900 : FOR( i = band_start[k]; i <= band_end[k]; i++ )
113 : {
114 : /*Eyy += (float) inp_vector[i] * inp_vector[i]; */
115 18176 : L_Eyy = L_add( L_Eyy, L_shl( L_inp_tmp[i], exp_norm ) ); /* Q1+exp_norm */
116 : }
117 724 : QEyy = add( 1, exp_norm );
118 :
119 724 : IF( L_Eyy > 0x0L )
120 : {
121 : /* Set gamma to be pulse gain which results in perfect quantized subband energy */
122 : /*gamma = (float) sqrt (pow (2.0f, band_energy[k]) / Eyy); */
123 :
124 : /* Pow part (pow(2.0f, band_energy) ) */
125 492 : L_temp = L_shr( L_band_energy[k], sub( SWB_BWE_LR_Qbe, 16 ) ); /* Q16 */
126 492 : temp_lo_fx = L_Extract_lc( L_temp, &temp_hi_fx );
127 492 : Qpow = sub( 14, temp_hi_fx );
128 492 : pow_fx = extract_l( Pow2( 14, temp_lo_fx ) ); /* Qpow */
129 :
130 : /* Div part ( pow (2.0f, band_energy[i])/Eyy ) */
131 492 : exp_normn = norm_s( pow_fx );
132 492 : exp_normn = sub( exp_normn, 1 );
133 492 : exp_normd = norm_l( L_Eyy );
134 492 : temp_fx = div_s( shl( pow_fx, exp_normn ), extract_h( L_shl( L_Eyy, exp_normd ) ) );
135 492 : Qdiv = add( sub( add( Qpow, exp_normn ), add( QEyy, exp_normd ) ), 31 );
136 :
137 492 : exp_norm = norm_s( temp_fx );
138 492 : temp_fx = shl( temp_fx, exp_norm );
139 492 : Qdiv = add( Qdiv, exp_norm );
140 :
141 : /* Sqrt part sqrt(pow (2.0f, band_energy[i])/Eyy) */
142 492 : Qgamma = add( Qdiv, 16 );
143 492 : IF( s_and( Qdiv, 1 ) == 0 ) /* Qdiv % 2 == 0 */
144 : {
145 251 : L_temp = Sqrt_l( L_shr( L_deposit_h( temp_fx ), 1 ), &exp_norm );
146 251 : L_temp = L_shr( L_temp, exp_norm );
147 251 : Qgamma = sub( shr( Qgamma, 1 ), 1 );
148 251 : gamma_fx = round_fx( L_temp ); /* Qgamma */
149 : }
150 : ELSE
151 : {
152 241 : L_temp = Sqrt_l( L_deposit_h( temp_fx ), &exp_norm );
153 241 : L_temp = L_shr( L_temp, exp_norm );
154 241 : Qgamma = shr( Qgamma, 1 );
155 241 : gamma_fx = round_fx( L_temp ); /* Qgamma */
156 : }
157 :
158 : /* Adjust gamma based on pulse density (0 bit MSE gain estimator) */
159 : /*pd = (float) npulses[k] / band_width[k]; */
160 492 : exp_normn = norm_s( npulses[k] );
161 492 : exp_normn = sub( exp_normn, 1 );
162 492 : exp_normd = norm_s( band_width[k] );
163 492 : pd_fx = div_s( shl( npulses[k], exp_normn ), shl( band_width[k], exp_normd ) ); /* 15 + (exp_norm - exp_normd) */
164 492 : Qpd = add( sub( exp_normn, exp_normd ), 15 );
165 :
166 492 : cond_fx = sub( shl_o( pd_fx, sub( 15, Qpd ), &Overflow ), pd_thresh_fx /*Q15*/ ); /* Q15 */
167 492 : Overflow = 0;
168 492 : move16(); /* allow overflow happen. */
169 492 : IF( cond_fx < 0 )
170 : {
171 : /*gain_tweak = (float) pow (2.0f, (ld_slope * log2_f (pd / pd_thresh))); */
172 : /* Div part */
173 374 : exp_normn = norm_s( pd_fx );
174 374 : exp_normn = sub( exp_normn, 1 );
175 374 : exp_normd = norm_s( pd_thresh_fx );
176 374 : div_pd_fx = div_s( shl( pd_fx, exp_normn ), shl( pd_thresh_fx, exp_normd ) ); /* Qpd+exp_normn - (15 + exp_normd) + 15 */
177 374 : Qdivpd = add( sub( add( Qpd, exp_normn ), add( 15, exp_normd ) ), 15 );
178 :
179 : /* Log2 part */
180 374 : exp_norm = norm_s( div_pd_fx );
181 374 : L_div_pd = L_deposit_h( shl( div_pd_fx, exp_norm ) );
182 374 : Qdivpd = add( add( Qdivpd, exp_norm ), 16 );
183 :
184 374 : frac = Log2_norm_lc( L_div_pd );
185 374 : exp = sub( 30, Qdivpd );
186 374 : L_tmp = L_Comp( exp, frac ); /* Q16 */
187 :
188 : /* Mult part */
189 374 : L_tmp = Mpy_32_16_1( L_tmp, ld_slope_fx ); /* Q16 */
190 :
191 : /* Pow part */
192 374 : temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
193 374 : Qtweak = sub( 14, temp_hi_fx );
194 374 : gain_tweak_fx = extract_l( Pow2( 14, temp_lo_fx ) );
195 :
196 : /*gamma *= gain_tweak; */
197 374 : L_tmp = L_mult( gamma_fx, gain_tweak_fx ); /* Qgamma+Qtweak+1 */
198 374 : exp_norm = norm_l( L_tmp );
199 374 : gamma_fx = round_fx_o( L_shl_o( L_tmp, exp_norm, &Overflow ), &Overflow );
200 374 : Qgamma = sub( add( add( Qgamma, Qtweak ), exp_norm ), 15 ); /*Qgamma+Qtweak+1+exp_norm-16; */
201 : }
202 :
203 492 : exp_shift = sub( SWB_BWE_LR_Qs - 1, Qgamma );
204 7155 : FOR( i = band_start[k]; i <= band_end[k]; i++ )
205 : {
206 : /*y2[i] = gamma * inp_vector[i]; */
207 6663 : L_tmp = L_mult( gamma_fx, (Word16) inp_vector[i] ); /* Qgamma+0+1=Qgamma+1 */
208 6663 : L_y2[i] = L_shl( L_tmp, exp_shift ); /* SWB_BWE_LR_Qs */
209 6663 : move32();
210 : }
211 : }
212 : }
213 :
214 32 : return;
215 : }
216 :
217 :
218 0 : void mdct_spectrum_denorm_ivas_fx(
219 : const Word32 inp_vector[], /* i : Q0 : */
220 : Word32 L_y2[], /* i/o : Qs : decoded spectrum */
221 : const Word16 band_start[], /* i : Q0 : table of start freq for every subband */
222 : const Word16 band_end[], /* i : Q0 : table of end freq for every subband */
223 : const Word16 band_width[], /* i : Q0 : table of bandwidth for every subband */
224 : const Word32 L_band_energy[], /* i : Qbe : band energy */
225 : const Word16 npulses[], /* i : Q0 : number of coded spectrum */
226 : const Word16 bands, /* i : Q0 : number of subbands */
227 : const Word16 ld_slope_fx, /* i : Q15 : */
228 : const Word16 pd_thresh_fx /* i : Q15 : */
229 : )
230 : {
231 : Word16 i, k;
232 : Word32 L_Eyy;
233 : Word32 L_tmp, L_temp;
234 : Word16 temp_fx, temp_lo_fx, temp_hi_fx;
235 : Word32 L_inp_tmp[L_FRAME48k];
236 : Word16 exp_norm;
237 : Word16 exp_safe;
238 : Word16 exp_normn, exp_normd;
239 :
240 : Word16 pd_fx;
241 : Word16 Qpd;
242 :
243 : Word16 div_pd_fx;
244 : Word16 Qdivpd;
245 : Word32 L_div_pd;
246 :
247 : Word16 frac, exp;
248 :
249 : Word16 gain_tweak_fx;
250 : Word16 Qtweak;
251 :
252 : Word16 exp_shift;
253 :
254 : Word16 QEyy;
255 : Word16 pow_fx;
256 : Word16 Qpow;
257 : Word16 Qdiv;
258 : Word16 Qgamma;
259 : Word16 gamma_fx;
260 :
261 : Word16 cond_fx;
262 :
263 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
264 0 : Flag Overflow = 0;
265 0 : move16(); /* allow overflow happen. */
266 : #endif
267 :
268 0 : exp_safe = 4; /* safe bit for overflow */
269 0 : move16();
270 :
271 0 : FOR( k = 0; k < bands; k++ )
272 : {
273 0 : L_tmp = L_deposit_l( 0 );
274 0 : FOR( i = band_start[k]; i <= band_end[k]; i++ )
275 : {
276 0 : L_inp_tmp[i] = L_mult( extract_l( inp_vector[i] ), extract_l( inp_vector[i] ) );
277 0 : move32(); /* Q0+Q0+1 */
278 0 : L_tmp = L_or( L_tmp, L_inp_tmp[i] );
279 : }
280 0 : exp_norm = norm_l( L_tmp );
281 0 : exp_norm = sub( exp_norm, exp_safe );
282 :
283 0 : L_Eyy = L_deposit_l( 0 );
284 0 : FOR( i = band_start[k]; i <= band_end[k]; i++ )
285 : {
286 : /*Eyy += (float) inp_vector[i] * inp_vector[i]; */
287 0 : L_Eyy = L_add( L_Eyy, L_shl( L_inp_tmp[i], exp_norm ) ); /* Q1+exp_norm */
288 : }
289 0 : QEyy = add( 1, exp_norm );
290 :
291 0 : IF( L_Eyy > 0x0L )
292 : {
293 : /* Set gamma to be pulse gain which results in perfect quantized subband energy */
294 : /*gamma = (float) sqrt (pow (2.0f, band_energy[k]) / Eyy); */
295 :
296 : /* Pow part (pow(2.0f, band_energy) ) */
297 0 : L_temp = L_shr( L_band_energy[k], sub( SWB_BWE_LR_Qbe, 16 ) );
298 0 : temp_lo_fx = L_Extract_lc( L_temp, &temp_hi_fx );
299 0 : Qpow = sub( 14, temp_hi_fx );
300 0 : pow_fx = extract_l( Pow2( 14, temp_lo_fx ) ); /* Qpow */
301 :
302 : /* Div part ( pow (2.0f, band_energy[i])/Eyy ) */
303 0 : exp_normn = norm_s( pow_fx );
304 0 : exp_normn = sub( exp_normn, 1 );
305 0 : exp_normd = norm_l( L_Eyy );
306 0 : temp_fx = div_s( shl( pow_fx, exp_normn ), extract_h( L_shl( L_Eyy, exp_normd ) ) ); /* ((Qpow + exp_norm) - (QEyy + exp_normd)) + 31 */
307 0 : Qdiv = add( sub( add( Qpow, exp_normn ), add( QEyy, exp_normd ) ), 31 );
308 :
309 0 : exp_norm = norm_s( temp_fx );
310 0 : temp_fx = shl( temp_fx, exp_norm ); /* Qdiv + exp_norm */
311 0 : Qdiv = add( Qdiv, exp_norm );
312 :
313 : /* Sqrt part sqrt(pow (2.0f, band_energy[i])/Eyy) */
314 0 : Qgamma = add( Qdiv, 16 );
315 0 : IF( s_and( Qdiv, 1 ) == 0 ) /* Qdiv % 2 == 0 */
316 : {
317 0 : L_temp = Sqrt_l( L_shr( L_deposit_h( temp_fx ), 1 ), &exp_norm );
318 0 : L_temp = L_shr( L_temp, exp_norm );
319 0 : Qgamma = sub( shr( Qgamma, 1 ), 1 );
320 0 : gamma_fx = round_fx( L_temp );
321 : }
322 : ELSE
323 : {
324 0 : L_temp = Sqrt_l( L_deposit_h( temp_fx ), &exp_norm );
325 0 : L_temp = L_shr( L_temp, exp_norm );
326 0 : Qgamma = shr( Qgamma, 1 );
327 0 : gamma_fx = round_fx( L_temp );
328 : }
329 :
330 : /* Adjust gamma based on pulse density (0 bit MSE gain estimator) */
331 : /*pd = (float) npulses[k] / band_width[k]; */
332 0 : exp_normn = norm_s( npulses[k] );
333 0 : exp_normn = sub( exp_normn, 1 );
334 0 : exp_normd = norm_s( band_width[k] );
335 0 : pd_fx = div_s( shl( npulses[k], exp_normn ), shl( band_width[k], exp_normd ) ); /* 15 + (exp_normn + exp_normd) */
336 0 : Qpd = add( sub( exp_normn, exp_normd ), 15 );
337 :
338 0 : cond_fx = sub( shl_o( pd_fx, sub( 15, Qpd ), &Overflow ), pd_thresh_fx /*Q15*/ ); /* Q15 */
339 0 : Overflow = 0;
340 0 : move16(); /* allow overflow happen. */
341 0 : IF( cond_fx < 0 )
342 : {
343 : /*gain_tweak = (float) pow (2.0f, (ld_slope * log2_f (pd / pd_thresh))); */
344 : /* Div part */
345 0 : exp_normn = norm_s( pd_fx );
346 0 : exp_normn = sub( exp_normn, 1 );
347 0 : exp_normd = norm_s( pd_thresh_fx );
348 0 : div_pd_fx = div_s( shl( pd_fx, exp_normn ), shl( pd_thresh_fx, exp_normd ) ); /* Qpd+exp_normn - (15 + exp_normd) + 15 */
349 0 : Qdivpd = add( sub( add( Qpd, exp_normn ), add( 15, exp_normd ) ), 15 );
350 :
351 : /* Log2 part */
352 0 : exp_norm = norm_s( div_pd_fx );
353 0 : L_div_pd = L_deposit_h( shl( div_pd_fx, exp_norm ) ); /* Qdivpd + exp_norm + 16 */
354 0 : Qdivpd = add( add( Qdivpd, exp_norm ), 16 );
355 :
356 0 : frac = Log2_norm_lc( L_div_pd );
357 0 : exp = sub( 30, Qdivpd );
358 0 : L_tmp = L_Comp( exp, frac ); /* Q16 */
359 :
360 : /* Mult part */
361 0 : L_tmp = Mpy_32_16_1( L_tmp, ld_slope_fx );
362 :
363 : /* Pow part */
364 0 : temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
365 0 : Qtweak = sub( 14, temp_hi_fx );
366 0 : gain_tweak_fx = extract_l( Pow2( 14, temp_lo_fx ) );
367 :
368 : /*gamma *= gain_tweak; */
369 0 : L_tmp = L_mult( gamma_fx, gain_tweak_fx ); /* Qgamma+Qtweak+1 */
370 0 : exp_norm = norm_l( L_tmp );
371 0 : gamma_fx = round_fx_o( L_shl_o( L_tmp, exp_norm, &Overflow ), &Overflow );
372 0 : Qgamma = sub( add( add( Qgamma, Qtweak ), exp_norm ), 15 ); /*Qgamma+Qtweak+1+exp_norm-16; */
373 : }
374 :
375 0 : exp_shift = sub( SWB_BWE_LR_Qs - 1, Qgamma );
376 0 : FOR( i = band_start[k]; i <= band_end[k]; i++ )
377 : {
378 : /*y2[i] = gamma * inp_vector[i]; */
379 0 : L_tmp = L_mult( gamma_fx, extract_l( inp_vector[i] ) ); /* Qgamma+0+1=Qgamma+1 */
380 0 : L_y2[i] = L_shl( L_tmp, exp_shift ); /* SWB_BWE_LR_Qs */
381 0 : move32();
382 : }
383 : }
384 : }
385 :
386 0 : return;
387 : }
388 :
389 : /*==========================================================================*/
390 : /* FUNCTION : void hq2_core_configure_fx() */
391 : /*--------------------------------------------------------------------------*/
392 : /* PURPOSE : */
393 : /*--------------------------------------------------------------------------*/
394 : /* INPUT ARGUMENTS : */
395 : /*--------------------------------------------------------------------------*/
396 : /* OUTPUT ARGUMENTS : */
397 : /* Word16 *qint o: Q13 */
398 : /* Word16 *eref o: Q10 */
399 : /* Word16 *bit_alloc_weight o: Q13 */
400 : /* Word16 *p2a_th o: Q11 */
401 : /* Word16 *pd_thresh o: Q15 */
402 : /* Word16 *ld_slope o: Q15 */
403 : /* Word16 *ni_coef o: Q14 */
404 : /*--------------------------------------------------------------------------*/
405 : /* INPUT/OUTPUT ARGUMENTS : */
406 : /*--------------------------------------------------------------------------*/
407 : /* RETURN ARGUMENTS : */
408 : /* _ None */
409 : /*--------------------------------------------------------------------------*/
410 : /* CALLED FROM : */
411 : /*==========================================================================*/
412 :
413 32 : void hq2_core_configure_fx(
414 : const Word16 frame_length, /* Q0 */
415 : const Word16 num_bits, /* Q0 */
416 : const Word16 is_transient, /* Q0 */
417 : Word16 *bands, /* Q0 */
418 : Word16 *length, /* Q0 */
419 : Word16 band_width[], /* Q0 */
420 : Word16 band_start[], /* Q0 */
421 : Word16 band_end[], /* Q0 */
422 : Word32 *L_qint, /* Q13 */
423 : Word16 *eref, /* Q10 */
424 : Word16 *bit_alloc_weight, /* Q13 */
425 : Word16 *gqlevs, /* Q0 */
426 : Word16 *Ngq, /* Q0 */
427 : Word16 *p2a_bands, /* Q0 */
428 : Word16 *p2a_th, /* Q11 */
429 : Word16 *pd_thresh, /* Q15 */
430 : Word16 *ld_slope, /* Q15 */
431 : Word16 *ni_coef, /* Q14 */
432 : Word32 L_bwe_br /* Q0 */
433 : )
434 : {
435 : const Xcore_Config *xcore_config_fx;
436 :
437 : Word16 i, k;
438 : Word16 bands_sh;
439 :
440 32 : xcore_config_fx = &xcore_config_32kHz_013200bps_long; /* default set for VC Warning */
441 :
442 32 : IF( EQ_16( frame_length, L_FRAME8k ) )
443 : {
444 0 : IF( is_transient )
445 : {
446 0 : IF( LE_16( num_bits, ACELP_7k20 / FRAMES_PER_SEC ) )
447 : {
448 0 : xcore_config_fx = &xcore_config_8kHz_007200bps_short;
449 : }
450 0 : ELSE IF( LE_16( num_bits, ACELP_8k00 / FRAMES_PER_SEC ) )
451 : {
452 0 : xcore_config_fx = &xcore_config_8kHz_008000bps_short;
453 : }
454 0 : ELSE IF( LE_16( num_bits, ACELP_13k20 / FRAMES_PER_SEC ) )
455 : {
456 0 : xcore_config_fx = &xcore_config_8kHz_013200bps_short;
457 : }
458 : ELSE
459 : {
460 0 : xcore_config_fx = &xcore_config_8kHz_016400bps_short;
461 : }
462 : }
463 : ELSE
464 : {
465 0 : IF( LE_16( num_bits, ACELP_7k20 / FRAMES_PER_SEC ) )
466 : {
467 0 : xcore_config_fx = &xcore_config_8kHz_007200bps_long;
468 : }
469 0 : ELSE IF( LE_16( num_bits, ACELP_8k00 / FRAMES_PER_SEC ) )
470 : {
471 0 : xcore_config_fx = &xcore_config_8kHz_008000bps_long;
472 : }
473 0 : ELSE IF( LE_16( num_bits, ACELP_13k20 / FRAMES_PER_SEC ) )
474 : {
475 0 : xcore_config_fx = &xcore_config_8kHz_013200bps_long;
476 : }
477 : ELSE
478 : {
479 0 : xcore_config_fx = &xcore_config_8kHz_016400bps_long;
480 : }
481 : }
482 : }
483 32 : ELSE IF( EQ_16( frame_length, L_FRAME16k ) )
484 : {
485 0 : IF( is_transient )
486 : {
487 0 : IF( LE_16( num_bits, ACELP_13k20 / FRAMES_PER_SEC ) )
488 : {
489 0 : xcore_config_fx = &xcore_config_16kHz_013200bps_short;
490 0 : move16();
491 : }
492 0 : ELSE IF( LE_16( num_bits, ACELP_16k40 / FRAMES_PER_SEC ) )
493 : {
494 0 : xcore_config_fx = &xcore_config_16kHz_016400bps_short;
495 0 : move16();
496 : }
497 : }
498 : ELSE
499 : {
500 0 : IF( LE_16( num_bits, ACELP_13k20 / FRAMES_PER_SEC ) )
501 : {
502 0 : xcore_config_fx = &xcore_config_16kHz_013200bps_long;
503 0 : move16();
504 : }
505 0 : ELSE IF( LE_16( num_bits, ACELP_16k40 / FRAMES_PER_SEC ) )
506 : {
507 0 : xcore_config_fx = &xcore_config_16kHz_016400bps_long;
508 0 : move16();
509 : }
510 : }
511 : }
512 : ELSE /* (frame_length == SWB) */
513 : {
514 32 : IF( is_transient ){
515 2 : IF( LE_32( L_bwe_br, ACELP_13k20 ) ){
516 2 : xcore_config_fx = &xcore_config_32kHz_013200bps_short;
517 2 : move16();
518 : }
519 0 : ELSE IF( LE_32( L_bwe_br, ACELP_16k40 ) )
520 : {
521 0 : xcore_config_fx = &xcore_config_32kHz_016400bps_short;
522 0 : move16();
523 : }
524 : }
525 : ELSE
526 : {
527 30 : IF( LE_32( L_bwe_br, ACELP_13k20 ) )
528 : {
529 30 : xcore_config_fx = &xcore_config_32kHz_013200bps_long;
530 30 : move16();
531 : }
532 0 : ELSE IF( LE_32( L_bwe_br, ACELP_16k40 ) )
533 : {
534 0 : xcore_config_fx = &xcore_config_32kHz_016400bps_long;
535 0 : move16();
536 : }
537 : }
538 : }
539 :
540 32 : *bands = xcore_config_fx->bands; /* Q0 */
541 32 : move16();
542 32 : *length = xcore_config_fx->bw; /* Q0 */
543 32 : move16();
544 32 : *L_qint = xcore_config_fx->L_qint; /* Q13 */
545 32 : move32();
546 :
547 32 : *eref = xcore_config_fx->eref; /* Q10 */
548 32 : move16();
549 32 : *bit_alloc_weight = xcore_config_fx->bit_alloc_weight; /* Q13 */
550 32 : move16();
551 32 : *gqlevs = xcore_config_fx->gqlevs; /* Q0 */
552 32 : move16();
553 32 : *Ngq = xcore_config_fx->Ngq; /* Q0 */
554 32 : move16();
555 :
556 32 : *p2a_bands = xcore_config_fx->p2a_bands; /* Q0 */
557 32 : move16();
558 32 : *p2a_th = xcore_config_fx->p2a_th; /* Q11 */
559 32 : move16();
560 :
561 32 : *pd_thresh = xcore_config_fx->pd_thresh; /* Q15 */
562 32 : move16();
563 32 : *ld_slope = xcore_config_fx->ld_slope; /* Q14 */
564 32 : move16();
565 32 : *ni_coef = xcore_config_fx->ni_coef; /* Q14 */
566 32 : move16();
567 :
568 : /*mvs2s_fx (xcore_config_fx->band_width, band_width, *bands); */
569 32 : Copy( xcore_config_fx->band_width, band_width, *bands ); /* Q0 */
570 :
571 : /* Expand band_width[] table for short windows */
572 32 : IF( is_transient )
573 : {
574 2 : bands_sh = *bands; /* Q0 */
575 2 : move16();
576 2 : *bands = shl( bands_sh, 2 ); /* Q0 */
577 2 : move16();
578 2 : *length = shl( *length, 2 ); /* Q0 */
579 2 : move16();
580 :
581 8 : FOR( i = 1; i <= 3; i++ )
582 : {
583 54 : FOR( k = 0; k < bands_sh; k++ )
584 : {
585 48 : band_width[i * bands_sh + k] = band_width[k]; /* Q0 */
586 48 : move16();
587 : }
588 : }
589 : }
590 :
591 : /* Formulate band_start and band_end tables from band_width table */
592 32 : band_start[0] = 0; /* Q0 */
593 32 : move16();
594 32 : band_end[0] = sub( band_width[0], 1 ); /* Q0 */
595 32 : move16();
596 724 : FOR( k = 1; k < *bands; k++ )
597 : {
598 692 : band_start[k] = add( band_start[k - 1], band_width[k - 1] ); /* Q0 */
599 692 : move16();
600 692 : band_end[k] = sub( add( band_start[k], band_width[k] ), 1 ); /* Q0 */
601 692 : move16();
602 : }
603 :
604 :
605 32 : return;
606 : }
607 :
608 : /*--------------------------------------------------------------------------*
609 : * reverse_transient_frame_energies()
610 : *
611 : *
612 : *--------------------------------------------------------------------------*/
613 :
614 2 : void reverse_transient_frame_energies_fx(
615 : Word32 L_band_energy[], /* o : Q14 : band energies */
616 : const Word16 bands /* i : Q0 : number of bands */
617 : )
618 : {
619 : Word16 k, k1, k2;
620 : Word32 L_be;
621 : Word16 bands_2, bands_4, bands_8;
622 : Word32 *p_be1, *p_be2;
623 :
624 2 : bands_2 = shr( bands, 1 ); /* Q0 */
625 2 : bands_4 = shr( bands, 2 ); /* Q0 */
626 2 : bands_8 = shr( bands, 3 ); /* Q0 */
627 :
628 2 : k1 = bands_4; /* Q0 */
629 2 : k2 = sub( bands_2, 1 ); /* Q0 */
630 2 : p_be1 = &L_band_energy[k1]; /* Q14 */
631 2 : p_be2 = &L_band_energy[k2]; /* Q14 */
632 10 : FOR( k = 0; k < bands_8; k++ )
633 : {
634 8 : L_be = *p_be1; /* Q14 */
635 8 : move32();
636 8 : *p_be1 = *p_be2; /* Q14 */
637 8 : move32();
638 8 : *p_be2 = L_be; /* Q14 */
639 8 : move32();
640 8 : p_be1++;
641 8 : p_be2--;
642 : }
643 :
644 2 : k1 = sub( bands, bands_4 ); /* 3*bands/4 Q0 */
645 2 : k2 = sub( bands, 1 ); /* Q0 */
646 2 : p_be1 = &L_band_energy[k1]; /* Q14 */
647 2 : p_be2 = &L_band_energy[k2]; /* Q14 */
648 10 : FOR( k = 0; k < bands_8; k++ )
649 : {
650 8 : L_be = *p_be1; /* Q14 */
651 8 : move32();
652 8 : *p_be1 = *p_be2; /* Q14 */
653 8 : move32();
654 8 : *p_be2 = L_be; /* Q14 */
655 8 : move32();
656 8 : p_be1++;
657 8 : p_be2--;
658 : }
659 :
660 2 : return;
661 : }
662 :
663 :
664 : /*--------------------------------------------------------------------------*
665 : * spt_shorten_domain_pre()
666 : *
667 : * Compute shorten subband if previous frame has spectral peak.
668 : *--------------------------------------------------------------------------*/
669 :
670 30 : void spt_shorten_domain_pre_fx(
671 : const Word16 band_start[], /* i: Starting position of sub band Q0*/
672 : const Word16 band_end[], /* i: End position of sub band Q0*/
673 : const Word16 prev_SWB_peak_pos[], /* i: Spectral peak Q0*/
674 : const Word16 BANDS, /* i: total number of bands Q0*/
675 : const Word32 L_bwe_br, /* i: bitrate information Q0*/
676 : Word16 new_band_start[], /* o: Starting position of new shorten sub band Q0*/
677 : Word16 new_band_end[], /* o: End position of new shorten sub band Q0*/
678 : Word16 new_band_width[] /* o: new sub band bandwidth Q0*/
679 : )
680 : {
681 : Word16 j;
682 : Word16 k;
683 : Word16 kpos;
684 :
685 : Word16 new_band_width_half;
686 : const Word16 *p_bw_SPT_tbl; /* pointer of bw_SPT_tbl */
687 :
688 30 : p_bw_SPT_tbl = bw_SPT_tbl[0]; /* Q0 */
689 30 : if ( EQ_32( L_bwe_br, HQ_16k40 ) )
690 : {
691 0 : p_bw_SPT_tbl = bw_SPT_tbl[1]; /* Q0 */
692 : }
693 :
694 30 : kpos = 0;
695 30 : move16();
696 30 : j = 0;
697 30 : move16();
698 150 : FOR( k = BANDS - SPT_SHORTEN_SBNUM; k < BANDS; k++ )
699 : {
700 120 : IF( prev_SWB_peak_pos[kpos] != 0 )
701 : {
702 1 : new_band_width[j] = p_bw_SPT_tbl[j]; /* Q0 */
703 :
704 : /*shorten the bandwidth for pulse resolution*/
705 1 : new_band_width_half = shr( new_band_width[j], 1 ); /* Q0 */
706 1 : move16();
707 1 : new_band_start[j] = sub( prev_SWB_peak_pos[kpos], new_band_width_half ); /* Q0 */
708 1 : move16();
709 1 : new_band_end[j] = add( prev_SWB_peak_pos[kpos], new_band_width_half ); /* Q0 */
710 1 : move16();
711 :
712 1 : IF( LT_16( new_band_start[j], band_start[k] ) )
713 : {
714 0 : new_band_start[j] = band_start[k]; /* Q0 */
715 0 : move16();
716 0 : new_band_end[j] = add( new_band_start[j], sub( new_band_width[j], 1 ) ); /* Q0 */
717 0 : move16();
718 : }
719 1 : ELSE IF( GT_16( new_band_end[j], band_end[k] ) )
720 : {
721 1 : new_band_end[j] = band_end[k]; /* Q0 */
722 1 : move16();
723 1 : new_band_start[j] = sub( new_band_end[j], sub( new_band_width[j], 1 ) ); /* Q0 */
724 1 : move16();
725 : }
726 : }
727 : ELSE
728 : {
729 119 : new_band_width[j] = p_bw_SPT_tbl[j]; /* Q0 */
730 :
731 : /*shorten the bandwidth for pulse resolution*/
732 119 : new_band_width_half = shr( new_band_width[j], 1 ); /* Q0 */
733 119 : move16();
734 119 : new_band_start[j] = sub( shr( add( band_start[k], band_end[k] ), 1 ), new_band_width_half ); /* Q0 */
735 119 : move16();
736 119 : new_band_end[j] = add( shr( add( band_start[k], band_end[k] ), 1 ), new_band_width_half ); /* Q0 */
737 119 : move16();
738 : }
739 :
740 120 : kpos++;
741 120 : j++;
742 : }
743 :
744 30 : return;
745 : }
746 :
747 : /*--------------------------------------------------------------------------*
748 : * spt_shorten_domain_band_save()
749 : *
750 : * Store the original subband information
751 : *--------------------------------------------------------------------------*/
752 :
753 30 : void spt_shorten_domain_band_save_fx(
754 : const Word16 bands, /* i: total subband Q0*/
755 : const Word16 band_start[], /* i: starting position of subband Q0*/
756 : const Word16 band_end[], /* i: end position of subband Q0*/
757 : const Word16 band_width[], /* i: band width of subband Q0*/
758 : Word16 org_band_start[], /* o: starting position of subband Q0*/
759 : Word16 org_band_end[], /* o: end position of subband Q0*/
760 : Word16 org_band_width[] /* o: band width of subband Q0*/
761 : )
762 : {
763 : Word16 k;
764 : Word16 kpos;
765 :
766 30 : kpos = 0;
767 30 : move16();
768 150 : FOR( k = bands - SPT_SHORTEN_SBNUM; k < bands; k++ )
769 : {
770 120 : org_band_start[kpos] = band_start[k]; /* Q0 */
771 120 : move16();
772 120 : org_band_end[kpos] = band_end[k]; /* Q0 */
773 120 : move16();
774 120 : org_band_width[kpos] = band_width[k]; /* Q0 */
775 120 : move16();
776 120 : kpos++;
777 : }
778 :
779 30 : return;
780 : }
781 :
782 : /*--------------------------------------------------------------------------*
783 : * spt_shorten_domain_band_restore()
784 : *
785 : * Restrore the subband information
786 : *--------------------------------------------------------------------------*/
787 :
788 30 : void spt_shorten_domain_band_restore_fx(
789 : const Word16 bands, /* i: total subband Q0*/
790 : Word16 band_start[], /* i/o: starting position of subband Q0*/
791 : Word16 band_end[], /* i/o: end position of subband Q0*/
792 : Word16 band_width[], /* i/o: band width of subband Q0*/
793 : const Word16 org_band_start[], /* o: starting position of subband Q0*/
794 : const Word16 org_band_end[], /* o: end position of subband Q0*/
795 : const Word16 org_band_width[] /* o: band width of subband Q0*/
796 : )
797 : {
798 : Word16 k;
799 : Word16 kpos;
800 :
801 30 : kpos = 0;
802 30 : move16();
803 150 : FOR( k = bands - SPT_SHORTEN_SBNUM; k < bands; k++ )
804 : {
805 120 : band_start[k] = org_band_start[kpos]; /* Q0 */
806 120 : move16();
807 120 : band_end[k] = org_band_end[kpos]; /* Q0 */
808 120 : move16();
809 120 : band_width[k] = org_band_width[kpos]; /* Q0 */
810 120 : move16();
811 120 : kpos++;
812 : }
813 :
814 30 : return;
815 : }
816 :
817 : /*--------------------------------------------------------------------------*
818 : * spt_swb_peakpos_tmp_save
819 : *
820 : * Save Peak position for every higher subband
821 : *--------------------------------------------------------------------------*/
822 :
823 30 : void spt_swb_peakpos_tmp_save_fx(
824 : const Word32 L_y2[], /* i: coded spectral information Qx*/
825 : const Word16 bands, /* i: total number of bands Q0*/
826 : const Word16 band_start[], /* i: starting position of subband Q0*/
827 : const Word16 band_end[], /* i: end position of subband Q0*/
828 : Word16 prev_SWB_peak_pos_tmp[] /* o: spectral peaks Q0*/
829 : )
830 : {
831 :
832 : Word16 i, j, k;
833 : Word32 L_peak_max;
834 : Word32 L_abs_y2;
835 :
836 30 : j = 0;
837 30 : move16();
838 150 : FOR( k = bands - SPT_SHORTEN_SBNUM; k < bands; k++ )
839 : {
840 120 : L_peak_max = L_deposit_l( 0 );
841 120 : prev_SWB_peak_pos_tmp[j] = 0;
842 120 : move16();
843 9480 : FOR( i = band_start[k]; i <= band_end[k]; i++ )
844 : {
845 9360 : L_abs_y2 = L_abs( L_y2[i] );
846 9360 : move32();
847 9360 : IF( LT_32( L_peak_max, L_abs_y2 ) )
848 : {
849 285 : L_peak_max = L_abs_y2; /* Qx */
850 285 : move32();
851 285 : prev_SWB_peak_pos_tmp[j] = i; /* Q0 */
852 285 : move16();
853 : }
854 : }
855 120 : j++;
856 : }
857 30 : return;
858 : }
859 :
860 : // already present need this one because appropriate and uses basops other than previous one.
861 :
862 0 : void bit_allocation_second_fx(
863 : Word32 *Rk, /* Q16 */
864 : Word32 *Rk_sort, /* Q16 */
865 : Word16 BANDS, /* Q0 */
866 : const Word16 *band_width, /* Q0 */
867 : Word16 *k_sort, /* Q0 */
868 : Word16 *k_num, /* Q0 */
869 : const Word16 *p2a_flags, /* Q0 */
870 : const Word16 p2a_bands, /* Q0 */
871 : const Word16 *last_bitalloc, /* Q0 */
872 : const Word16 input_frame /* Q0 */
873 : )
874 : {
875 0 : Word16 k, k2 = 0;
876 0 : move16();
877 : Word16 ever_bits[BANDS_MAX], ever_sort[BANDS_MAX]; /*Q12 */
878 0 : Word16 class_flag = 0;
879 0 : move16();
880 0 : Word16 rk_temp = 32767, ever_temp = 32767; /*Q12 */
881 0 : move16();
882 0 : move16();
883 : Word16 exp;
884 : Word16 tmp;
885 : Word32 L_tmp;
886 :
887 0 : FOR( k = 0; k < BANDS; k++ )
888 : {
889 0 : test();
890 0 : test();
891 0 : test();
892 0 : IF( ( ( GE_16( k_sort[k], sub( BANDS, p2a_bands ) ) ) && ( EQ_16( p2a_flags[k_sort[k]], 1 ) ) ) ||
893 : ( ( GE_16( k_sort[k], ( BANDS - 2 ) ) ) && ( EQ_16( last_bitalloc[k_sort[k] - ( BANDS - 2 )], 1 ) ) ) )
894 : {
895 0 : exp = norm_s( band_width[k_sort[k]] );
896 0 : tmp = shl( band_width[k_sort[k]], exp ); /*Q(exp) */
897 0 : tmp = div_s( 16384, tmp ); /*Q(15+14-exp = 29-exp) */
898 0 : L_tmp = Mult_32_16( Rk_sort[k], tmp ); /* Q(16+29-exp-15 = 30-exp) */
899 0 : tmp = sub( 18, exp );
900 0 : ever_bits[k] = extract_l( L_shr( L_tmp, tmp ) ); /*Q12 */
901 0 : IF( LT_16( ever_bits[k], rk_temp ) )
902 : {
903 0 : rk_temp = ever_bits[k]; /* Q12 */
904 0 : move16();
905 0 : k2 = k;
906 0 : move16();
907 : }
908 0 : class_flag = 1;
909 0 : move16();
910 : }
911 : }
912 0 : test();
913 0 : IF( class_flag == 0 || EQ_16( input_frame, L_FRAME8k ) )
914 : {
915 0 : FOR( k = 0; k < BANDS; k++ )
916 : {
917 0 : test();
918 0 : IF( LT_16( k_sort[k], sub( BANDS, p2a_bands ) ) && Rk_sort[k] > 0 )
919 : {
920 0 : exp = norm_s( band_width[k_sort[k]] );
921 0 : tmp = shl( band_width[k_sort[k]], exp ); /*Q(exp) */
922 0 : tmp = div_s( 16384, tmp ); /*Q(15+14-exp = 29-exp) */
923 0 : L_tmp = Mult_32_16( Rk_sort[k], tmp ); /* Q(16+29-exp-15 = 30-exp) */
924 0 : tmp = sub( 18, exp );
925 0 : ever_sort[k] = extract_l( L_shr( L_tmp, tmp ) ); /*Q12 */
926 0 : IF( LT_16( ever_sort[k], ever_temp ) )
927 : {
928 0 : ever_temp = ever_sort[k]; /* Q12 */
929 0 : move16();
930 0 : k2 = k;
931 0 : move16();
932 : }
933 : }
934 : }
935 : }
936 :
937 0 : k_num[0] = k2; /* Q0 */
938 0 : move16();
939 0 : IF( EQ_16( k_sort[k2], sub( BANDS, 1 ) ) )
940 : {
941 0 : FOR( k = 0; k < BANDS; k++ )
942 : {
943 0 : if ( EQ_16( k_sort[k], sub( k_sort[k2], 1 ) ) )
944 : {
945 0 : k_num[1] = k; /* Q0 */
946 0 : move16();
947 : }
948 : }
949 : }
950 0 : ELSE IF( k_sort[k2] == 0 )
951 : {
952 0 : FOR( k = 0; k < BANDS; k++ )
953 : {
954 0 : if ( EQ_16( k_sort[k], add( k_sort[k2], 1 ) ) )
955 : {
956 0 : k_num[1] = k; /* Q0 */
957 0 : move16();
958 : }
959 : }
960 : }
961 : ELSE
962 : {
963 0 : IF( LT_32( Rk[k_sort[k2] - 1], Rk[k_sort[k2] + 1] ) )
964 : {
965 0 : FOR( k = 0; k < BANDS; k++ )
966 : {
967 0 : if ( EQ_16( k_sort[k], sub( k_sort[k2], 1 ) ) )
968 : {
969 0 : k_num[1] = k; /* Q0 */
970 0 : move16();
971 : }
972 : }
973 : }
974 : ELSE
975 : {
976 0 : FOR( k = 0; k < BANDS; k++ )
977 : {
978 0 : if ( EQ_16( k_sort[k], add( k_sort[k2], 1 ) ) )
979 : {
980 0 : k_num[1] = k; /* Q0 */
981 0 : move16();
982 : }
983 : }
984 : }
985 : }
986 0 : }
|