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 : #include <stdint.h>
37 : #include <stdlib.h>
38 : #include "options.h" /* Compilation switches */
39 : #include "rom_com.h" /* Static table prototypes FIP version */
40 : #include "stl.h" /* required for wmc_tool */
41 : #include "prot_fx.h"
42 : #include "ivas_prot_fx.h"
43 :
44 : /*--------------------------------------------------------------------------*
45 : * Local function prototypes
46 : *--------------------------------------------------------------------------*/
47 :
48 : static void overlap_hq_bwe_fx( const Word32 *hq_swb_overlap_buf, Word32 *coeff_out, const Word16 n_swb_overlap_offset, const Word16 n_swb_overlap, const Word16 *R, const Word16 num_env_bands, const Word16 num_sfm, const Word16 *sfm_end );
49 :
50 :
51 : /*--------------------------------------------------------------------------*
52 : * hq_swb_harmonic_calc_norm_envelop()
53 : *
54 : * Calculate normalization envelop
55 : *--------------------------------------------------------------------------*/
56 :
57 1957 : void hq_swb_harmonic_calc_norm_envelop_fx(
58 : const Word32 *L_SWB_signal, /* i : input signal Q=12*/
59 : Word32 *L_envelope, /* o : output envelope Q=12*/
60 : const Word16 L_swb_norm, /* i : length of normaliztion Q0*/
61 : const Word16 SWB_flength /* i : length of input signal Q0*/
62 : )
63 : {
64 :
65 : Word16 lookback;
66 : Word16 env_index;
67 : Word16 n_freq;
68 : Word16 n_lag_now;
69 : Word16 n_lag;
70 : Word16 i;
71 : Word32 L_tmp;
72 :
73 1957 : lookback = shr( L_swb_norm, 1 ); /*Q0*/
74 1957 : env_index = 0;
75 1957 : move16();
76 42310 : FOR( n_freq = 0; n_freq < lookback; n_freq++ )
77 : {
78 40353 : n_lag_now = add( lookback, n_freq );
79 :
80 : /* Apply MA filter */
81 40353 : L_envelope[env_index] = EPSILLON_FX;
82 40353 : move16();
83 :
84 1424037 : FOR( n_lag = 0; n_lag < n_lag_now; n_lag++ )
85 : {
86 1383684 : L_tmp = L_abs( L_SWB_signal[n_lag] ); /*Q12*/
87 1383684 : L_envelope[env_index] = L_add_sat( L_envelope[env_index], L_tmp ); /*Q12*/
88 1383684 : move32();
89 : }
90 40353 : env_index = add( env_index, 1 );
91 : }
92 :
93 1957 : n_lag_now = L_swb_norm; /*Q0*/
94 1957 : move16();
95 :
96 315631 : FOR( n_freq = 0; n_freq < SWB_flength - L_swb_norm; n_freq++ )
97 : {
98 : /* Apply MA filter */
99 313674 : L_envelope[env_index] = EPSILLON_FX;
100 313674 : move16();
101 12983068 : FOR( n_lag = 0; n_lag < n_lag_now; n_lag++ )
102 : {
103 12669394 : L_tmp = L_abs( L_SWB_signal[( n_freq + n_lag )] ); /*Q12*/
104 12669394 : L_envelope[env_index] = L_add_sat( L_envelope[env_index], L_tmp ); /*Q12*/
105 12669394 : move32();
106 : }
107 313674 : env_index = add( env_index, 1 );
108 : }
109 :
110 1957 : i = 0;
111 1957 : move16();
112 43244 : FOR( n_freq = SWB_flength - L_swb_norm; n_freq < SWB_flength - lookback; n_freq++ )
113 : {
114 41287 : n_lag_now = sub( L_swb_norm, i );
115 :
116 : /* Apply MA filter */
117 41287 : L_envelope[env_index] = L_deposit_l( EPSILLON_FX );
118 41287 : move32();
119 1504920 : FOR( n_lag = 0; n_lag < n_lag_now; n_lag++ )
120 : {
121 1463633 : L_tmp = L_abs( L_SWB_signal[( n_freq + n_lag )] ); /*Q12*/
122 1463633 : L_envelope[env_index] = L_add_sat( L_envelope[env_index], L_tmp ); /*Q12*/
123 1463633 : move32();
124 : }
125 41287 : env_index = add( env_index, 1 );
126 41287 : i = add( i, 1 );
127 : }
128 :
129 1957 : return;
130 : }
131 :
132 :
133 : /*--------------------------------------------------------------------------*
134 : * noise_level_calc_fx()
135 : *
136 : * Calculate noise level and limited band
137 : *--------------------------------------------------------------------------*/
138 :
139 1529 : void limit_band_noise_level_calc_fx(
140 : const Word16 *wnorm, /* i : reordered norm of sub-vectors Q0*/
141 : Word16 *limit, /* o : highest band of bit allocation Q0*/
142 : const Word32 core_brate, /* i : bit rate Q0*/
143 : Word16 *noise_level /* o : noise level Q15*/
144 : )
145 : {
146 : Word16 ener_limit, ener_sum;
147 : Word16 i;
148 : Word16 nb_sfm;
149 : Word32 fact;
150 : Word16 tmp;
151 :
152 1529 : nb_sfm = *limit; /*Q0*/
153 1529 : move16();
154 1529 : ener_limit = 0;
155 1529 : move16();
156 1529 : *noise_level = 0;
157 1529 : move16();
158 16819 : FOR( i = 0; i < 10; i++ )
159 : {
160 15290 : ener_limit = add( ener_limit, wnorm[i] ); /*Q0*/
161 15290 : *noise_level = add( *noise_level, abs_s( sub( wnorm[i + 1], wnorm[i] ) ) ); /*Q15*/
162 15290 : move16();
163 : }
164 1529 : ener_sum = ener_limit; /*Q0*/
165 1529 : move16();
166 :
167 1529 : tmp = sub( nb_sfm, 1 );
168 31723 : FOR( i = 10; i < tmp; i++ )
169 : {
170 30194 : ener_sum = add( ener_sum, wnorm[i] ); /*Q0*/
171 30194 : *noise_level = add( *noise_level, abs_s( sub( wnorm[i + 1], wnorm[i] ) ) ); /*Q15*/
172 30194 : move16();
173 : }
174 1529 : ener_sum = add( ener_sum, wnorm[nb_sfm - 1] ); /*Q0*/
175 :
176 :
177 1529 : fact = 2022929597; /*Q31*/
178 1529 : move32();
179 1529 : if ( LT_32( core_brate, HQ_BWE_CROSSOVER_BRATE ) )
180 : {
181 786 : fact = L_add( 1900523029, 1 ); /*Q31*/
182 : }
183 :
184 1529 : fact = Mult_32_16( fact, ener_sum ); /*Q16*/
185 1529 : i = 9;
186 1529 : move16();
187 1529 : test();
188 26955 : WHILE( LT_32( L_deposit_h( ener_limit ), fact ) && LT_16( add( i, 1 ), nb_sfm ) )
189 : {
190 25426 : ener_limit = add( ener_limit, wnorm[++i] ); /*Q0*/
191 25426 : test();
192 : }
193 1529 : *limit = i;
194 1529 : move16();
195 :
196 : /* calculate noise level for spectrum filling */
197 1529 : if ( *noise_level < 0 )
198 : {
199 0 : *noise_level = 0;
200 0 : move16();
201 : }
202 :
203 1529 : IF( GE_16( *noise_level, shr( ener_sum, 2 ) ) )
204 : {
205 302 : *noise_level = 0;
206 302 : move16();
207 : }
208 : ELSE
209 : {
210 1227 : IF( ener_sum != 0 )
211 : {
212 1227 : *noise_level = sub( 8192 /*Q15*/, div_s( *noise_level, ener_sum ) );
213 : }
214 : ELSE
215 : {
216 0 : *noise_level = 8192; /*Q15*/
217 : }
218 1227 : move16();
219 : }
220 :
221 1529 : return;
222 : }
223 :
224 : /*--------------------------------------------------------------------------*
225 : * build_nf_codebook_fx()
226 : *
227 : * Build noise-fill codebook for HQ mode
228 : * NOTE: Q values preliminary
229 : *--------------------------------------------------------------------------*/
230 :
231 6499 : Word16 build_nf_codebook_fx( /* o : Number of coefficients in nf codebook Q=0*/
232 : const Word16 flag_32K_env_ho, /* i : Envelope attenuation hangover flag Q=0*/
233 : const Word16 *coeff, /* i : Coded spectral coefficients Q=12*/
234 : const Word16 *sfm_start, /* i : Subband start indices Q=0*/
235 : const Word16 *sfmsize, /* i : Subband widths Q=0*/
236 : const Word16 *sfm_end, /* i : Subband end indices Q=0*/
237 : const Word16 last_sfm, /* i : Last coded band Q=0*/
238 : const Word16 *R, /* i : Per-band bit allocation Q=0*/
239 : Word16 *CodeBook, /* o : Noise-fill codebook Q=12*/
240 : Word16 *CodeBook_mod /* o : Densified noise-fill codebook Q=12*/
241 : )
242 : {
243 : Word16 sfm_base;
244 : Word16 sfm;
245 : Word16 E_cb_vec;
246 : Word16 i, j;
247 : Word16 cb_size;
248 :
249 : /* Build codebook */
250 :
251 6499 : cb_size = 0;
252 6499 : move16();
253 :
254 195334 : FOR( sfm = 0; sfm <= last_sfm; sfm++ )
255 : {
256 188835 : IF( R[sfm] != 0 )
257 : {
258 140138 : IF( flag_32K_env_ho )
259 : {
260 : /* Build compressed (+/- 1) noise-fill codebook */
261 7040 : sfm_base = sfm_start[sfm]; /*Q0*/
262 7040 : move16();
263 19253 : FOR( i = 0; i < sfmsize[sfm] / 8; i++ )
264 : {
265 12213 : E_cb_vec = 0;
266 12213 : move16();
267 109917 : FOR( j = sfm_base + i * 8; j < sfm_base + ( i + 1 ) * 8; j++ )
268 : {
269 97704 : IF( coeff[j] > 0 )
270 : {
271 17211 : CodeBook_mod[cb_size] = 1 << 12; /*Q12*/
272 17211 : move16();
273 17211 : E_cb_vec = add( E_cb_vec, 1 );
274 : }
275 80493 : ELSE IF( coeff[j] < 0 )
276 : {
277 17414 : CodeBook_mod[cb_size] = -1 * ( 1 << 12 ); /*Q12*/
278 17414 : move16();
279 17414 : E_cb_vec = add( E_cb_vec, 1 );
280 : }
281 : ELSE
282 : {
283 63079 : CodeBook_mod[cb_size] = 0;
284 63079 : move16();
285 : }
286 97704 : cb_size = add( cb_size, 1 );
287 : }
288 :
289 12213 : if ( E_cb_vec < 2 )
290 : {
291 2872 : cb_size = sub( cb_size, 8 );
292 : }
293 : }
294 : }
295 : ELSE
296 : {
297 1843664 : FOR( j = sfm_start[sfm]; j < sfm_end[sfm]; j++ )
298 : {
299 1710566 : CodeBook[cb_size] = coeff[j]; /*Q12*/
300 1710566 : move16();
301 1710566 : cb_size = add( cb_size, 1 );
302 : }
303 : }
304 : }
305 : }
306 :
307 6499 : IF( flag_32K_env_ho )
308 : {
309 75134 : FOR( j = 0; j < cb_size; j++ )
310 : {
311 74728 : IF( CodeBook_mod[j] != 0 )
312 : {
313 : /* Densify codebook */
314 32664 : CodeBook[j] = -4096; /*Q12*/
315 32664 : move16();
316 32664 : if ( CodeBook_mod[j] > 0 )
317 : {
318 16278 : CodeBook[j] = 4096; /*Q12*/
319 16278 : move16();
320 : }
321 :
322 32664 : IF( CodeBook_mod[cb_size - j - 1] != 0 )
323 : {
324 14310 : CodeBook[j] = shl( CodeBook[j], 1 ); /*Q12*/
325 14310 : move16(); /* Mult by 2 */
326 : }
327 : }
328 : ELSE
329 : {
330 42064 : CodeBook[j] = CodeBook_mod[cb_size - j - 1]; /*Q12*/
331 42064 : move16();
332 : }
333 : }
334 : }
335 :
336 6499 : return cb_size; /*Q0*/
337 : }
338 :
339 :
340 : /*--------------------------------------------------------------------------*
341 : * find_last_band()
342 : *
343 : * Find the last band which has bits allocated
344 : *--------------------------------------------------------------------------*/
345 :
346 12216 : Word16 find_last_band_fx( /* o : index of last band */
347 : const Word16 *bitalloc, /* i : bit allocation Q0*/
348 : const Word16 nb_sfm /* i : number of possibly coded bands Q0*/
349 : )
350 : {
351 : Word16 sfm, core_sfm;
352 :
353 12216 : core_sfm = sub( nb_sfm, 1 ); /*Q0*/
354 :
355 175706 : FOR( sfm = nb_sfm - 1; sfm >= 0; sfm-- )
356 : {
357 175706 : IF( bitalloc[sfm] != 0 )
358 : {
359 12216 : core_sfm = sfm; /*Q0*/
360 12216 : move16();
361 12216 : BREAK;
362 : }
363 : }
364 :
365 12216 : return core_sfm; /*Q0*/
366 : }
367 :
368 : /*--------------------------------------------------------------------------*
369 : * apply_noisefill_HQ()
370 : *
371 : * Inject noise in non-coded bands
372 : *--------------------------------------------------------------------------*/
373 :
374 6499 : void apply_noisefill_HQ_fx(
375 : const Word16 *R, /* i : bit allocation Q0 */
376 : const Word16 length, /* i : input frame length Q0 */
377 : const Word16 flag_32K_env_ho, /* i : envelope stability hangover flag Q0 */
378 : const Word32 L_core_brate, /* i : core bit rate Q0 */
379 : const Word16 last_sfm, /* i : last coded subband Q0 */
380 : const Word16 *CodeBook, /* i : Noise-fill codebook Q12 */
381 : const Word16 *CodeBook_mod, /* i : Densified noise-fill codebook Q12 */
382 : const Word16 cb_size, /* i : Codebook length Q0 */
383 : const Word16 *sfm_start, /* i : Subband start coefficient Q0 */
384 : const Word16 *sfm_end, /* i : Subband end coefficient Q0 */
385 : const Word16 *sfmsize, /* i : Subband band width Q0 */
386 : Word16 *coeff /* i/o: coded/noisefilled spectrum Q12 */
387 : )
388 : {
389 : Word16 sfm;
390 : Word16 cb_pos;
391 : Word16 E_corr;
392 : Word16 cb_buff[PVQ_MAX_BAND_SIZE];
393 : Word16 i, j;
394 : Word16 istart;
395 : UWord16 lsb;
396 : Word32 L_E_cb_vec;
397 : Word32 L_E_corr;
398 :
399 6499 : test();
400 6499 : IF( ( GE_16( length, L_FRAME32k ) ) || ( NE_32( L_core_brate, HQ_32k ) ) )
401 : {
402 : /* Read from codebook */
403 6499 : cb_pos = 0;
404 6499 : move16();
405 :
406 195334 : FOR( sfm = 0; sfm <= last_sfm; sfm++ )
407 : {
408 188835 : IF( R[sfm] == 0 )
409 : {
410 48697 : IF( EQ_16( flag_32K_env_ho, 1 ) )
411 : {
412 4871 : L_E_cb_vec = L_deposit_l( 0 );
413 4871 : IF( LT_16( sfm, 20 ) )
414 : {
415 35649 : FOR( i = 0; i < sfmsize[sfm]; i++ )
416 : {
417 32216 : cb_buff[i] = CodeBook_mod[cb_pos++]; /*Q12*/
418 32216 : move16();
419 32216 : L_E_cb_vec = L_mac0_sat( L_E_cb_vec, cb_buff[i], cb_buff[i] ); /*Q24 (12+12) */
420 :
421 32216 : if ( GE_16( cb_pos, cb_size ) )
422 : {
423 51 : cb_pos = 0;
424 51 : move16();
425 : }
426 : }
427 : }
428 : ELSE
429 : {
430 32262 : FOR( i = 0; i < sfmsize[sfm]; i++ )
431 : {
432 30824 : cb_buff[i] = CodeBook[cb_pos++]; /*Q12*/
433 30824 : move16();
434 30824 : L_E_cb_vec = L_mac0_sat( L_E_cb_vec, cb_buff[i], cb_buff[i] ); /*Q24 (12+12) */
435 :
436 30824 : if ( GE_16( cb_pos, cb_size ) )
437 : {
438 208 : cb_pos = 0;
439 208 : move16();
440 : }
441 : }
442 : }
443 :
444 : /*E_corr = E_cb_vec / ((float) sfmsize[sfm]); */
445 4871 : Mpy_32_16_ss( L_E_cb_vec, inv_tbl_fx[sfmsize[sfm]], &L_E_corr, &lsb ); /*Q24 (24+15+1-16) */
446 4871 : move16();
447 :
448 : /*E_corr = 1.0f / (float)sqrt(E_corr); */
449 4871 : L_E_corr = Isqrt( L_E_corr ); /*Q19 (31-24/2) */
450 4871 : E_corr = extract_h( L_shl( L_E_corr, 10 ) ); /*Q13 (13-(19-16)) */
451 :
452 4871 : istart = sfm_start[sfm]; /*Q0*/
453 4871 : move16();
454 67911 : FOR( j = istart; j < sfm_end[sfm]; j++ )
455 : {
456 : /*coeff[j] = cb_buff[j - istart] * E_corr; */
457 63040 : coeff[j] = extract_h( L_shl( L_mult( cb_buff[j - istart], E_corr ), 2 ) ); /*Q12 (12+13+1+2-16) */
458 63040 : move16();
459 : }
460 : }
461 : ELSE
462 : {
463 737560 : FOR( j = sfm_start[sfm]; j < sfm_end[sfm]; j++ )
464 : {
465 693734 : coeff[j] = CodeBook[cb_pos++]; /*Q12*/
466 693734 : move16();
467 693734 : if ( GE_16( cb_pos, cb_size ) )
468 : {
469 1544 : cb_pos = 0;
470 1544 : move16();
471 : }
472 : }
473 : }
474 : }
475 : }
476 : }
477 :
478 6499 : return;
479 : }
480 :
481 : /*--------------------------------------------------------------------------*
482 : * harm_bwe_fine_fx()
483 : *
484 : * Prepare harmonic BWE fine structure
485 : *--------------------------------------------------------------------------*/
486 :
487 728 : void harm_bwe_fine_fx(
488 : const Word16 *R, /* i : bit allocation Q0*/
489 : const Word16 last_sfm, /* i : last coded subband Q0*/
490 : const Word16 high_sfm, /* i : higher transition band to BWE Q0*/
491 : const Word16 num_sfm, /* i : total number of bands Q0*/
492 : const Word16 *norm, /* i : quantization indices for norms Q0*/
493 : const Word16 *sfm_start, /* i : Subband start coefficient Q0*/
494 : const Word16 *sfm_end, /* i : Subband end coefficient Q0*/
495 : Word16 *prev_L_swb_norm, /* i/o: last normalize length Q0*/
496 : Word16 *coeff, /* i/o: coded/noisefilled normalized spectrum Q12*/
497 : Word32 *coeff_out, /* o : coded/noisefilled spectrum Q12*/
498 : Word16 *coeff_fine /* o : BWE fine structure Q15*/
499 : )
500 : {
501 : Word16 sfm;
502 : Word16 i;
503 : Word32 normq;
504 : Word16 SWB_signal[L_HARMONIC_EXC];
505 : Word32 envelope[L_HARMONIC_EXC], L_signal[L_HARMONIC_EXC];
506 : Word16 enve_lo[L_HARMONIC_EXC], enve_hi[L_HARMONIC_EXC];
507 : Word16 *src, *dst, *end;
508 : Word16 norm_signal;
509 :
510 728 : Word16 norm_width = 64;
511 728 : move16();
512 :
513 : /* shape the spectrum */
514 19311 : FOR( sfm = 0; sfm <= last_sfm; sfm++ )
515 : {
516 18583 : IF( R[sfm] != 0 )
517 : {
518 14871 : normq = dicn_fx[norm[sfm]]; /*Q14*/
519 14871 : move32();
520 :
521 222823 : FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
522 : {
523 207952 : coeff_out[i] = L_shl( Mult_32_16( normq, coeff[i] ), 1 ); /*12 14+12+1+1-16 */
524 207952 : move32();
525 : }
526 : }
527 : ELSE
528 : {
529 50512 : FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
530 : {
531 46800 : coeff_out[i] = L_deposit_l( 0 ); /*Q12*/
532 46800 : move16();
533 : }
534 : }
535 : }
536 :
537 : /* excitation replication */
538 728 : Copy32( coeff_out, L_signal, L_HARMONIC_EXC ); /*Q12*/
539 728 : calc_normal_length_fx_32( HQ_CORE, coeff_out, HQ_HARMONIC, -1, &norm_width, prev_L_swb_norm );
540 728 : hq_swb_harmonic_calc_norm_envelop_fx( L_signal, envelope, norm_width, L_HARMONIC_EXC );
541 :
542 : /* Normalize with envelope */
543 147784 : FOR( i = 0; i < L_HARMONIC_EXC; i++ )
544 : {
545 147056 : IF( L_signal[i] > 0 )
546 : {
547 21882 : norm_signal = norm_l( envelope[i] );
548 21882 : enve_lo[i] = L_Extract_lc( L_shl( envelope[i], norm_signal ), &enve_hi[i] ); /*Q12+norm_signal-16*/
549 21882 : L_signal[i] = Div_32( L_signal[i], enve_hi[i], enve_lo[i] ); /*Q31 - norm_signal*/
550 21882 : SWB_signal[i] = round_fx_sat( L_shl_sat( L_signal[i], norm_signal ) ); /*Q15*/
551 21882 : move16();
552 21882 : move16();
553 21882 : move32();
554 : }
555 : ELSE
556 : {
557 125174 : norm_signal = norm_l( envelope[i] );
558 125174 : enve_lo[i] = L_Extract_lc( L_shl( envelope[i], norm_signal ), &enve_hi[i] ); /*Q12+norm_signal-16*/
559 125174 : L_signal[i] = L_negate( Div_32( L_negate( L_signal[i] ), enve_hi[i], enve_lo[i] ) ); /*Q31 - norm_signal*/
560 125174 : SWB_signal[i] = round_fx_sat( L_shl_sat( L_signal[i], norm_signal ) ); /*Q15*/
561 125174 : move16();
562 125174 : move16();
563 125174 : move32();
564 : }
565 : }
566 :
567 728 : dst = coeff_fine + sfm_end[last_sfm]; /*Q15*/
568 728 : end = coeff_fine + sfm_end[num_sfm - 1]; /*Q15*/
569 :
570 728 : IF( LE_16( sub( sfm_end[last_sfm], sfm_end[high_sfm] ), ( L_HARMONIC_EXC - START_EXC ) ) )
571 : {
572 544 : src = SWB_signal + START_EXC + sub( sfm_end[last_sfm], sfm_end[high_sfm] ); /*Q15*/
573 : }
574 : ELSE
575 : {
576 184 : src = SWB_signal + L_HARMONIC_EXC - 1; /*Q15*/
577 : }
578 :
579 2427 : WHILE( dst < end )
580 : {
581 1699 : logic32();
582 153149 : WHILE( dst < end && src < &SWB_signal[L_HARMONIC_EXC] )
583 : {
584 151450 : *dst++ = *src++; /*Q15*/
585 151450 : move16();
586 : }
587 1699 : src--;
588 :
589 1699 : logic32();
590 163017 : WHILE( dst < end && src >= &SWB_signal[START_EXC] )
591 : {
592 161318 : *dst++ = *src--; /*Q15*/
593 161318 : move16();
594 : }
595 1699 : src++;
596 : }
597 :
598 728 : return;
599 : }
600 :
601 : /*--------------------------------------------------------------------------*
602 : * hvq_bwe_fine()
603 : *
604 : * Prepare HVQ BWE fine structure
605 : *--------------------------------------------------------------------------*/
606 :
607 1229 : void hvq_bwe_fine_fx(
608 : const Word16 last_sfm, /* i : last coded subband Q0 */
609 : const Word16 num_sfm, /* i : total number of bands Q0 */
610 : const Word16 *sfm_end, /* i : Subband end coefficient Q0 */
611 : const Word16 *peak_idx, /* i : Peak index Q0 */
612 : const Word16 Npeaks, /* i : Number of peaks Q0 */
613 : Word16 *peak_pos, /* o : Peak positions Q0 */
614 : Word16 *prev_L_swb_norm, /* i/o: last normalize length Q0 */
615 : Word32 *L_coeff, /* i : coded/noisefilled normalized spectrum Q12 */
616 : Word16 *bwe_peaks, /* o : Positions of peaks in BWE Q0 */
617 : Word16 *coeff_fine /* o : HVQ BWE fine structure Q15 */
618 : )
619 : {
620 : Word16 i, j;
621 : Word16 SWB_signal[L_HARMONIC_EXC];
622 : Word32 L_envelope[L_HARMONIC_EXC];
623 : Word16 *src, *dst, *end;
624 : Word16 *peak_dst, *peak_src;
625 1229 : Word16 norm_width = 64;
626 : Word16 tmp;
627 : Word16 shift, shift2;
628 : Word32 L_tmp;
629 : UWord16 lsb;
630 :
631 1229 : calc_normal_length_fx_32( HQ_CORE, L_coeff, HQ_HVQ, -1, &norm_width, prev_L_swb_norm );
632 :
633 1229 : hq_swb_harmonic_calc_norm_envelop_fx( L_coeff, L_envelope, norm_width, L_HARMONIC_EXC );
634 :
635 : /* Normalize with envelope */
636 249487 : FOR( i = 0; i < L_HARMONIC_EXC; i++ )
637 : {
638 : /*SWB_signal[i] = SWB_signal[i] / envelope[i]; */
639 :
640 248258 : shift = norm_l( L_envelope[i] );
641 248258 : tmp = round_fx_sat( L_shl_sat( L_envelope[i], shift ) ); /* 12+s-16=Q(-4+s) */
642 : /* Avoid division by zero */
643 248258 : if ( tmp == 0 )
644 : {
645 0 : tmp = 1 << 14;
646 0 : move16();
647 : }
648 :
649 248258 : tmp = div_s( 1 << 14, tmp ); /* 15+14-(-4+s)=Q(33-s) */
650 248258 : Mpy_32_16_ss( L_coeff[i], tmp, &L_tmp, &lsb ); /* 12+33-s+1-16=Q(30-s) */
651 248258 : shift2 = add( shift, 1 );
652 248258 : tmp = round_fx( L_shl( L_tmp, shift2 ) ); /* 30-s+s+1-16=Q(15) */
653 248258 : SWB_signal[i] = add( tmp, extract_l( L_shr( lsb, sub( 32, shift2 ) ) ) ); /* Q15 */
654 248258 : move16();
655 : /*SWB_signal[i] = round_fx(L_shl(L_tmp, add(shift, 1))); // 30-s+s+1-16=Q(15) */
656 : }
657 :
658 1229 : dst = coeff_fine; /*Q15*/
659 1229 : end = coeff_fine + sfm_end[num_sfm - 1] - sfm_end[last_sfm]; /*Q15*/
660 :
661 1229 : src = SWB_signal + START_EXC; /*Q15*/
662 1229 : peak_src = peak_pos + START_EXC; /*Q0*/
663 :
664 22321 : FOR( i = 0; i < Npeaks; i++ )
665 : {
666 21092 : if ( LT_16( peak_idx[i], L_HARMONIC_EXC ) )
667 : {
668 16398 : peak_pos[peak_idx[i]] = 1;
669 16398 : move16();
670 : }
671 : }
672 :
673 1229 : i = sub( L_HARMONIC_EXC, 1 );
674 21534 : WHILE( i-- > 0 )
675 : {
676 21534 : IF( EQ_16( peak_pos[i], 1 ) )
677 : {
678 1229 : BREAK;
679 : }
680 : }
681 :
682 1229 : if ( LT_16( i, 180 ) )
683 : {
684 267 : i = 180;
685 267 : move16();
686 : }
687 :
688 18216 : FOR( j = L_HARMONIC_EXC - 1; j > i + 1; j-- )
689 : {
690 16987 : SWB_signal[j] = 0;
691 16987 : move16();
692 : }
693 :
694 1229 : peak_dst = bwe_peaks + sfm_end[last_sfm]; /*Q0*/
695 4223 : WHILE( dst < end )
696 : {
697 2994 : test();
698 353962 : WHILE( dst < end && src < &SWB_signal[L_HARMONIC_EXC] )
699 : {
700 350968 : *dst++ = *src++; /*Q15*/
701 350968 : move16();
702 350968 : *peak_dst++ = *peak_src++; /*Q0*/
703 350968 : move16();
704 : }
705 2994 : peak_src--; /*Q0*/
706 2994 : src--;
707 :
708 2994 : test();
709 281434 : WHILE( dst < end && src >= &SWB_signal[START_EXC] )
710 : {
711 278440 : *dst++ = *src--; /*Q15*/
712 278440 : move16();
713 278440 : *peak_dst++ = *peak_src--; /*Q0*/
714 278440 : move16();
715 : }
716 2994 : peak_src++; /*Q0*/
717 2994 : src++;
718 : }
719 :
720 1229 : return;
721 : }
722 :
723 : /*--------------------------------------------------------------------------*
724 : * hq_fold_bwe_fx()
725 : *
726 : * HQ mode folding BWE
727 : *--------------------------------------------------------------------------*/
728 :
729 2470 : void hq_fold_bwe_fx(
730 : const Word16 last_sfm, /* i : last coded subband Q0 */
731 : const Word16 *sfm_end, /* i : Subband end coefficient Q0 */
732 : const Word16 num_sfm, /* i : Number of subbands Q0 */
733 : Word16 *coeff /* i/o: coded/noisefilled normalized spectrum Q12 */
734 : )
735 : {
736 : Word16 low_coeff;
737 : Word16 first_coeff;
738 : Word16 *src, *dst, *end;
739 :
740 2470 : low_coeff = shr( sfm_end[last_sfm], 1 ); /*Q0*/
741 2470 : src = coeff + sfm_end[last_sfm] - 1; /*Q12*/
742 :
743 2470 : first_coeff = sfm_end[last_sfm]; /*Q0*/
744 2470 : move16();
745 2470 : dst = coeff + sfm_end[last_sfm]; /*Q12*/
746 2470 : end = coeff + sfm_end[num_sfm - 1]; /*Q12*/
747 :
748 5503 : WHILE( dst < end )
749 : {
750 3033 : test();
751 414154 : WHILE( dst < end && src >= &coeff[low_coeff] )
752 : {
753 411121 : test();
754 411121 : *dst++ = *src--; /*Q12*/
755 411121 : move16();
756 : }
757 :
758 3033 : src++;
759 3033 : test();
760 222076 : WHILE( dst < end && src < &coeff[first_coeff] )
761 : {
762 219043 : test();
763 219043 : *dst++ = *src++; /*Q12*/
764 219043 : move16();
765 : }
766 : }
767 2470 : return;
768 : }
769 :
770 : /*--------------------------------------------------------------------------*
771 : * apply_nf_gain()
772 : *
773 : * Apply noise fill gain
774 : *--------------------------------------------------------------------------*/
775 :
776 6417 : void apply_nf_gain_fx(
777 : const Word16 nf_idx, /* i : noise fill gain index Q0 */
778 : const Word16 last_sfm, /* i : last coded subband Q0 */
779 : const Word16 *R, /* i : bit allocation Q0 */
780 : const Word16 *sfm_start, /* i : Subband start coefficient Q0 */
781 : const Word16 *sfm_end, /* i : Subband end coefficient Q0 */
782 : Word16 *coeff /* i/o: coded/noisefilled normalized spectrum Q12 */
783 : )
784 : {
785 : Word16 sfm;
786 : Word16 j;
787 :
788 193217 : FOR( sfm = 0; sfm <= last_sfm; sfm++ )
789 : {
790 186800 : IF( R[sfm] == 0 )
791 : {
792 801577 : FOR( j = sfm_start[sfm]; j < sfm_end[sfm]; j++ )
793 : {
794 : /* Scale NoiseFill */
795 753150 : coeff[j] = shr( coeff[j], nf_idx ); /*Q12*/
796 753150 : move16();
797 : }
798 : }
799 : }
800 :
801 6417 : return;
802 : }
803 :
804 :
805 : /*--------------------------------------------------------------------------*
806 : * harm_bwe_fx()
807 : *
808 : * HQ Harmonic BWE
809 : *--------------------------------------------------------------------------*/
810 :
811 708 : void ivas_harm_bwe_fx(
812 : const Word16 *coeff_fine, /* i : fine structure for BWE Q12*/
813 : const Word16 *coeff, /* i : coded/noisefilled normalized spectrum Q12*/
814 : const Word16 num_sfm, /* i : Number of subbands Q0*/
815 : const Word16 *sfm_start, /* i : Subband start coefficient Q0*/
816 : const Word16 *sfm_end, /* i : Subband end coefficient Q0*/
817 : const Word16 last_sfm, /* i : last coded subband Q0*/
818 : const Word16 *R, /* i : bit allocation Q0*/
819 : const Word16 prev_hq_mode, /* i : previous hq mode Q0*/
820 : Word16 *norm, /* i/o: quantization indices for norms Q0*/
821 : Word16 *noise_level, /* i/o: noise levels for harmonic modes Q15*/
822 : Word16 *prev_noise_level, /* i/o: noise factor in previous frame Q15*/
823 : Word16 *bwe_seed, /* i/o: random seed for generating BWE input Q0*/
824 : Word32 *coeff_out, /* o : coded/noisefilled spectrum Q12*/
825 : const Word16 element_mode /* i : IVAS element mode Q0*/
826 : )
827 : {
828 : Word16 i, j;
829 : Word16 sfm, band_width;
830 : Word32 normq, L_tmp, L_tmp2;
831 : Word32 E_L;
832 708 : Word16 alfa = 16384;
833 708 : move16();
834 : Word16 tmp, tmp1, exp1;
835 : Word16 beta;
836 : Word32 *src, *dst;
837 :
838 708 : move16(); /* alfa */
839 :
840 18805 : FOR( sfm = 0; sfm <= last_sfm; sfm++ )
841 : {
842 18097 : IF( R[sfm] == 0 )
843 : {
844 3613 : normq = dicn_fx[norm[sfm]]; /*Q14 */
845 3613 : move16();
846 :
847 49445 : FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
848 : {
849 45832 : coeff_out[i] = L_shl( Mult_32_16( normq, coeff[i] ), 1 ); /*Q12*/
850 45832 : move32();
851 : }
852 : }
853 : }
854 708 : noise_level[1] = noise_level[0]; /*Q15*/
855 708 : move16();
856 :
857 : /* shaping the BWE spectrum further by envelopes and noise factors */
858 708 : L_tmp = L_mult( 29491 /*0.9 in Q15*/, prev_noise_level[0] ); /* 15 +1 +15 */
859 708 : noise_level[0] = round_fx( L_mac( L_tmp, 3277 /*0.1 in Q15*/, noise_level[0] ) ); /*15 */
860 708 : move16();
861 :
862 708 : L_tmp = L_mult( 29491 /*0.9 in Q15*/, prev_noise_level[1] ); /*Q31*/
863 708 : noise_level[1] = round_fx( L_mac( L_tmp, 3277 /*0.1 in Q15*/, noise_level[1] ) ); /*Q15*/
864 708 : move16();
865 :
866 708 : test();
867 708 : IF( ( prev_hq_mode == HQ_NORMAL ) || EQ_16( prev_hq_mode, HQ_GEN_SWB ) )
868 : {
869 129 : IF( LT_16( noise_level[0], 8192 ) )
870 : {
871 129 : noise_level[0] = shl( noise_level[0], 2 ); /*Q15*/
872 129 : move16();
873 : }
874 :
875 129 : IF( LT_16( noise_level[1], 8192 ) )
876 : {
877 129 : noise_level[1] = shl( noise_level[1], 2 ); /*Q15*/
878 129 : move16();
879 : }
880 : }
881 :
882 5829 : FOR( i = add( last_sfm, 1 ); i < num_sfm; i++ )
883 : {
884 5121 : E_L = 1;
885 5121 : move32();
886 311073 : FOR( j = sfm_start[i]; j < sfm_end[i]; j++ )
887 : {
888 305952 : L_tmp = L_mult0( coeff_fine[j], coeff_fine[j] ); /*Q30 */
889 305952 : E_L = L_add( E_L, L_shr( L_tmp, 6 ) ); /*Q24 */
890 : }
891 :
892 5121 : normq = dicn_fx[norm[i]]; /*Q14*/
893 5121 : move32();
894 :
895 5121 : alfa = noise_level[0]; /*Q15*/
896 5121 : move16();
897 5121 : IF( GT_16( i, 27 ) )
898 : {
899 3387 : alfa = noise_level[1]; /*Q15*/
900 3387 : move16();
901 : }
902 :
903 5121 : band_width = sub( sfm_end[i], sfm_start[i] ); /* Q0 */
904 5121 : exp1 = norm_l( E_L );
905 5121 : IF( EQ_16( exp1, 0 ) )
906 : {
907 0 : E_L = Mult_32_16( E_L, inv_tbl_fx[band_width] ); /* Q24 (24+15+1-16) */ /*24+15+1-16 */
908 0 : tmp = div_l( E_L, sub( 32767, alfa ) ); /*Q24-15-1 =8 */
909 0 : tmp = s_max( 1, tmp );
910 0 : L_tmp = L_deposit_h( tmp ); /*24 */
911 0 : E_L = Isqrt( L_tmp ); /* Q19 (31-24/2) */
912 : }
913 : ELSE
914 : {
915 5121 : exp1 = sub( exp1, 1 );
916 5121 : E_L = Mult_32_16( L_shl( E_L, exp1 ), inv_tbl_fx[band_width] ); /* Q24+exp1 (24+exp1+15+1-16) */
917 5121 : tmp = div_l( E_L, sub( 32767, alfa ) ); /*Q24+exp1-15-1 =8+exp1 */
918 5121 : tmp = s_max( 1, tmp );
919 5121 : L_tmp = L_shl( L_deposit_l( tmp ), sub( 16, exp1 ) ); /*24 8+exp1+16-exp1 */
920 5121 : E_L = Isqrt( L_tmp ); /* Q19 (31-24/2) */
921 : }
922 :
923 5121 : exp1 = norm_s( alfa );
924 5121 : tmp1 = shl( alfa, exp1 ); /*Q15+exp1*/
925 5121 : IF( EQ_16( element_mode, EVS_MONO ) )
926 : {
927 0 : exp1 = add( 1, exp1 );
928 : }
929 : #ifdef DEBUGGING
930 : else
931 : {
932 : // PMT("VERIFY if this really matches IVAS float")
933 : }
934 : #endif
935 5121 : tmp1 = s_max( tmp1, 16384 );
936 5121 : tmp1 = div_s( 16384, tmp1 );
937 5121 : L_tmp2 = L_deposit_h( tmp1 );
938 5121 : L_tmp2 = Isqrt_lc( L_tmp2, &exp1 ); /*Q31 - exp1*/
939 :
940 5121 : beta = round_fx_sat( L_shl_sat( L_tmp2, exp1 ) ); /*Q15 */
941 5121 : beta = shr( beta, 1 ); /*Q15*/
942 :
943 :
944 311073 : FOR( sfm = sfm_start[i]; sfm < sfm_end[i]; sfm++ )
945 : {
946 305952 : L_tmp = Mult_32_16( E_L, coeff_fine[sfm] ); /*Q19 19 + 15 +1-16 */
947 305952 : L_tmp = L_shl_sat( L_tmp, 9 ); /*Q28 */
948 305952 : tmp = Random( bwe_seed ); /*Q15 */
949 305952 : L_tmp2 = L_shr( L_mult( beta, tmp ), 3 ); /* Q28 31-3 15+15 +1-3 */
950 305952 : L_tmp = L_add_sat( L_tmp, L_tmp2 ); /*Q28 */
951 305952 : coeff_out[sfm] = L_shl_sat( Mult_32_32( L_tmp, normq ), 1 ); /*Q12 28 +14 +1 -31 */
952 305952 : move32();
953 : }
954 : }
955 :
956 708 : prev_noise_level[0] = noise_level[0]; /*Q15*/
957 708 : move16();
958 708 : prev_noise_level[1] = noise_level[1]; /*Q15*/
959 708 : move16();
960 :
961 708 : src = &coeff_out[( sfm_end[last_sfm] + L_HARMONIC_EXC - START_EXC )]; /*Q12 */
962 :
963 708 : dst = src - 1; /*Q12*/
964 12036 : FOR( i = 0; i < 16; i++ )
965 : {
966 11328 : *src = Mult_32_16( *src, hvq_bwe_fac_fx[i] ); /* Q12 (12+15+1-16) */
967 11328 : move32();
968 11328 : src++;
969 11328 : *dst = Mult_32_16( *dst, hvq_bwe_fac_fx[i] ); /* Q12 (12+15+1-16) */
970 11328 : move32();
971 11328 : dst--;
972 : }
973 708 : IF( EQ_16( num_sfm, 33 ) )
974 : {
975 635 : set32_fx( &coeff_out[800], 0, 160 );
976 : }
977 708 : return;
978 : }
979 :
980 20 : void harm_bwe_fx(
981 : const Word16 *coeff_fine, /* i : fine structure for BWE Q12*/
982 : const Word16 *coeff, /* i : coded/noisefilled normalized spectrum Q12*/
983 : const Word16 num_sfm, /* i : Number of subbands Q0*/
984 : const Word16 *sfm_start, /* i : Subband start coefficient Q0*/
985 : const Word16 *sfm_end, /* i : Subband end coefficient Q0*/
986 : const Word16 last_sfm, /* i : last coded subband Q0*/
987 : const Word16 *R, /* i : bit allocation Q0*/
988 : const Word16 prev_hq_mode, /* i : previous hq mode Q0*/
989 : Word16 *norm, /* i/o: quantization indices for norms Q0*/
990 : Word16 *noise_level, /* i/o: noise levels for harmonic modes Q15*/
991 : Word16 *prev_noise_level, /* i/o: noise factor in previous frame Q15*/
992 : Word16 *bwe_seed, /* i/o: random seed for generating BWE input Q0*/
993 : Word32 *coeff_out, /* o : coded/noisefilled spectrum Q12*/
994 : const Word16 element_mode /* i : IVAS element mode Q0*/
995 : )
996 : {
997 : Word16 i, j;
998 : Word16 sfm, band_width;
999 : Word32 normq, L_tmp, L_tmp2;
1000 : Word32 E_L;
1001 20 : Word16 alfa = 16384;
1002 20 : move16();
1003 : Word16 tmp, tmp1, exp1;
1004 : Word16 beta;
1005 : Word32 *src, *dst;
1006 :
1007 20 : move16(); /* alfa */
1008 :
1009 506 : FOR( sfm = 0; sfm <= last_sfm; sfm++ )
1010 : {
1011 486 : IF( R[sfm] == 0 )
1012 : {
1013 99 : normq = dicn_fx[norm[sfm]]; /*Q14 */
1014 99 : move16();
1015 :
1016 1067 : FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
1017 : {
1018 968 : coeff_out[i] = L_shl( Mult_32_16( normq, coeff[i] ), 1 ); /*12 Q(14 +12+1-16 +1) */
1019 968 : move32();
1020 : }
1021 : }
1022 : }
1023 20 : noise_level[1] = noise_level[0]; /*Q15*/
1024 20 : move16();
1025 :
1026 : /* shaping the BWE spectrum further by envelopes and noise factors */
1027 20 : L_tmp = L_mult( 29491, prev_noise_level[0] ); /* 15 +1 +15 */
1028 20 : noise_level[0] = round_fx( L_mac( L_tmp, 3277, noise_level[0] ) ); /*15 */
1029 20 : move16();
1030 :
1031 20 : L_tmp = L_mult( 29491 /*0.9 in Q15*/, prev_noise_level[1] ); /*Q31*/
1032 20 : noise_level[1] = round_fx( L_mac( L_tmp, 3277, noise_level[1] ) ); /*Q15*/
1033 20 : move16();
1034 :
1035 20 : test();
1036 20 : IF( prev_hq_mode == HQ_NORMAL || EQ_16( prev_hq_mode, HQ_GEN_SWB ) )
1037 : {
1038 10 : IF( LT_16( noise_level[0], 8192 /*Q15*/ ) )
1039 : {
1040 10 : noise_level[0] = shl( noise_level[0], 2 ); /*Q15*/
1041 10 : move16();
1042 : }
1043 :
1044 10 : IF( LT_16( noise_level[1], 8192 /*Q15*/ ) )
1045 : {
1046 10 : noise_level[1] = shl( noise_level[1], 2 ); /*Q15*/
1047 10 : move16();
1048 : }
1049 : }
1050 :
1051 154 : FOR( i = add( last_sfm, 1 ); i < num_sfm; i++ )
1052 : {
1053 134 : E_L = 1;
1054 134 : move32();
1055 6950 : FOR( j = sfm_start[i]; j < sfm_end[i]; j++ )
1056 : {
1057 6816 : L_tmp = L_mult0( coeff_fine[j], coeff_fine[j] ); /*Q30 */
1058 6816 : E_L = L_add( E_L, L_shr( L_tmp, 6 ) ); /*Q24 */
1059 : }
1060 :
1061 134 : normq = dicn_fx[norm[i]]; /*Q14*/
1062 134 : move32();
1063 :
1064 134 : alfa = noise_level[0]; /*Q15*/
1065 134 : move16();
1066 134 : if ( GT_16( i, 27 ) )
1067 : {
1068 60 : alfa = noise_level[1]; /*Q15*/
1069 60 : move16();
1070 : }
1071 :
1072 134 : band_width = sub( sfm_end[i], sfm_start[i] ); /* */
1073 134 : exp1 = norm_l( E_L );
1074 134 : IF( exp1 == 0 )
1075 : {
1076 0 : E_L = Mult_32_16( E_L, inv_tbl_fx[band_width] ); /* Q24 (24+15+1-16) */ /*24+15+1-16 */
1077 0 : tmp = div_l( E_L, sub( 32767, alfa ) ); /*Q24-15-1 =8 */
1078 0 : tmp = s_max( 1, tmp );
1079 0 : L_tmp = L_deposit_h( tmp ); /*24 */
1080 0 : E_L = Isqrt( L_tmp ); /* Q19 (31-24/2) */
1081 : }
1082 : ELSE
1083 : {
1084 134 : exp1 = sub( exp1, 1 );
1085 134 : E_L = Mult_32_16( L_shl( E_L, exp1 ), inv_tbl_fx[band_width] ); /* Q24+exp1 (24+exp1+15+1-16) */
1086 134 : tmp = div_l( E_L, sub( 32767, alfa ) ); /*Q24+exp1-15-1 =8+exp1 */
1087 134 : tmp = s_max( 1, tmp );
1088 134 : L_tmp = L_shl( L_deposit_l( tmp ), sub( 16, exp1 ) ); /*24 8+exp1+16-exp1 */
1089 134 : E_L = Isqrt( L_tmp ); /* Q19 (31-24/2) */
1090 : }
1091 :
1092 134 : exp1 = norm_s( alfa );
1093 134 : tmp1 = shl( alfa, exp1 );
1094 134 : if ( EQ_16( element_mode, EVS_MONO ) )
1095 : {
1096 134 : exp1 = add( 1, exp1 );
1097 : }
1098 : #ifdef DEBUGGING
1099 : else
1100 : {
1101 : // PMT("VERIFY if this really matches IVAS float")
1102 : }
1103 : #endif
1104 134 : tmp1 = s_max( tmp1, 16384 );
1105 134 : tmp1 = div_s( 16384, tmp1 ); /*Q15*/
1106 134 : L_tmp2 = L_deposit_h( tmp1 ); /*Q31*/
1107 134 : L_tmp2 = Isqrt_lc( L_tmp2, &exp1 ); /*Q31 - exp1*/
1108 :
1109 134 : beta = round_fx( L_shl( L_tmp2, exp1 ) ); /*Q15*/
1110 134 : beta = shr( beta, 1 ); /*Q15 */
1111 :
1112 :
1113 6950 : FOR( sfm = sfm_start[i]; sfm < sfm_end[i]; sfm++ )
1114 : {
1115 6816 : L_tmp = Mult_32_16( E_L, coeff_fine[sfm] ); /*Q19 19 + 15 +1-16 */
1116 6816 : L_tmp = L_shl_sat( L_tmp, 9 ); /*Q28 */
1117 6816 : tmp = Random( bwe_seed ); /*Q15 */
1118 6816 : L_tmp2 = L_shr( L_mult( beta, tmp ), 3 ); /* Q28 31-3 15+15 +1-3 */
1119 6816 : L_tmp = L_add_sat( L_tmp, L_tmp2 ); /*Q28 */
1120 6816 : coeff_out[sfm] = L_shl_sat( Mult_32_32( L_tmp, normq ), 1 ); /*Q12 28 +14 +1 -31 */
1121 6816 : move32();
1122 : }
1123 : }
1124 :
1125 20 : prev_noise_level[0] = noise_level[0]; /*Q15*/
1126 20 : move16();
1127 20 : prev_noise_level[1] = noise_level[1]; /*Q15*/
1128 20 : move16();
1129 :
1130 20 : src = &coeff_out[( sfm_end[last_sfm] + L_HARMONIC_EXC - START_EXC )]; /*Q12 */
1131 :
1132 20 : dst = src - 1;
1133 340 : FOR( i = 0; i < 16; i++ )
1134 : {
1135 320 : *src = Mult_32_16( *src, hvq_bwe_fac_fx[i] ); /* Q12 (12+15+1-16) */
1136 320 : move32();
1137 320 : src++;
1138 320 : *dst = Mult_32_16( *dst, hvq_bwe_fac_fx[i] ); /* Q12 (12+15+1-16) */
1139 320 : move32();
1140 320 : dst--;
1141 : }
1142 20 : IF( EQ_16( num_sfm, 33 ) )
1143 : {
1144 0 : set32_fx( &coeff_out[800], 0, 160 );
1145 : }
1146 20 : return;
1147 : }
1148 :
1149 : /*--------------------------------------------------------------------------*
1150 : * HVQ_bwe_fx()
1151 : *
1152 : * HQ HVQ BWE
1153 : *--------------------------------------------------------------------------*/
1154 :
1155 1229 : void hvq_bwe_fx(
1156 : const Word32 *L_coeff, /* i : coded/noisefilled normalized spectrum Q12 */
1157 : const Word16 *coeff_fine, /* i : coded/noisefilled normalized spectrum Qin */
1158 : const Word16 *sfm_start, /* i : Subband start coefficient Q0 */
1159 : const Word16 *sfm_end, /* i : Subband end coefficient Q0 */
1160 : const Word16 *sfm_len, /* i : Subband length Q0 */
1161 : const Word16 last_sfm, /* i : last coded subband Q0 */
1162 : const Word16 prev_hq_mode, /* i : previous hq mode Q0 */
1163 : const Word16 *bwe_peaks, /* i : HVQ bwe peaks Q0 */
1164 : const Word16 bin_th, /* i : HVQ transition bin Q0 */
1165 : const Word16 num_sfm, /* i : Number of bands Q0 */
1166 : const Word32 core_brate, /* i : Core bitrate Q0 */
1167 : const Word16 *R, /* i : Bit allocation */
1168 : Word16 *norm, /* i/o: quantization indices for norms Q0 */
1169 : Word16 *noise_level, /* i/o: noise levels for harmonic modes Q15 */
1170 : Word16 *prev_noise_level, /* i/o: noise factor in previous frame Q15 */
1171 : Word16 *bwe_seed, /* i/o: random seed for generating BWE input Q0 */
1172 : Word32 *L_coeff_out, /* o : coded/noisefilled spectrum Qout*/
1173 : const Word16 qin,
1174 : const Word16 qout )
1175 : {
1176 : Word16 i, j;
1177 : Word16 N;
1178 : Word32 L_normq;
1179 : Word32 L_E;
1180 1229 : Word32 L_tmp_norm = 0;
1181 1229 : move32();
1182 1229 : Word16 bwe_noise_th = 0;
1183 1229 : move16();
1184 : Word16 peak_band, low, high, sel_norm;
1185 : Word16 norm_ind;
1186 : Word32 *L_src, *L_dst;
1187 : Word16 istart, iend;
1188 1229 : Word16 offset = sfm_end[last_sfm]; /*Q0*/
1189 :
1190 : /* Fx specific variables */
1191 : Word32 L_tmp0, L_tmp1;
1192 : Word16 tmp, tmp2, band_size;
1193 : Word16 last_norm_ind;
1194 : Word16 shift, power_shift;
1195 : Word16 coeff_s[L_FRAME48k];
1196 : Word16 j_N;
1197 : Word16 n_c;
1198 : UWord16 lsb;
1199 :
1200 1229 : move32(); /* L_tmp_norm */
1201 1229 : move16(); /* bwe_noise_th */
1202 :
1203 1229 : bwe_noise_th = add( bin_th, shr( sub( sfm_end[( num_sfm - 1 )], bin_th ), 1 ) );
1204 1229 : logqnorm_fx( &L_coeff_out[sfm_start[last_sfm]], qout, &norm[last_sfm], 40, sfm_len[last_sfm], 0 );
1205 1229 : move16();
1206 :
1207 : /* shaping the BWE spectrum further by envelopes and noise factors */
1208 1229 : noise_level[0] = round_fx( L_mac( L_mult( 29491 /*0.9 Q15*/, prev_noise_level[0] ), 3277 /*0.1 Q15*/, noise_level[0] ) ); /* Q15 (15+15+1-16) */
1209 1229 : noise_level[1] = round_fx( L_mac( L_mult( 29491 /*0.9 Q15*/, prev_noise_level[1] ), 3277 /*0.1 Q15*/, noise_level[1] ) ); /* Q15 (15+15+1-16) */
1210 1229 : move16();
1211 1229 : move16();
1212 :
1213 1229 : test();
1214 1229 : IF( prev_hq_mode == HQ_NORMAL || EQ_16( prev_hq_mode, HQ_GEN_SWB ) )
1215 : {
1216 117 : IF( LT_16( noise_level[0], 8192 /* 0.25f */ ) )
1217 : {
1218 117 : noise_level[0] = shl( noise_level[0], 2 ); /*Q15*/
1219 117 : move16();
1220 : }
1221 :
1222 117 : IF( LT_16( noise_level[1], 8192 /* 0.25f */ ) )
1223 : {
1224 117 : noise_level[1] = shl( noise_level[1], 2 ); /*Q15*/
1225 117 : move16();
1226 : }
1227 : }
1228 :
1229 1229 : norm_ind = add( last_sfm, 1 );
1230 1229 : IF( LT_32( core_brate, HQ_BWE_CROSSOVER_BRATE ) )
1231 : {
1232 708 : peak_band = 0;
1233 708 : move16();
1234 :
1235 708 : tmp = 1;
1236 708 : move16();
1237 46020 : FOR( i = sfm_start[norm_ind]; i < sfm_end[norm_ind + 1]; i++ )
1238 : {
1239 45312 : tmp2 = abs_s( coeff_fine[i - offset] ); /*Qin*/
1240 45312 : tmp = s_max( tmp, tmp2 );
1241 : }
1242 708 : band_size = sub( sfm_end[norm_ind + 1], sfm_start[norm_ind] );
1243 :
1244 : /* Headroom for square and accumulate */
1245 708 : shift = sub( norm_s( tmp ), sqac_headroom_fx[band_size] );
1246 708 : L_E = L_deposit_l( 1 );
1247 46020 : FOR( i = sfm_start[norm_ind]; i < sfm_end[norm_ind + 1]; i++ )
1248 : {
1249 45312 : if ( bwe_peaks[i] )
1250 : {
1251 1981 : peak_band = 1;
1252 1981 : move16();
1253 : }
1254 : /* E_L += coeff_fine[i-offset] * coeff_fine[i-offset]; */
1255 45312 : coeff_s[i] = shl( coeff_fine[i - offset], shift ); /*Qin*/
1256 45312 : move16(); /* Q15 + shift */
1257 45312 : L_E = L_mac0( L_E, coeff_s[i], coeff_s[i] ); /* Q2*(qin + shift) */
1258 : }
1259 708 : power_shift = shl( shift, 1 );
1260 :
1261 708 : L_E = L_shr( L_E, sub( power_shift, sub( 28, shl( qin, 1 ) ) ) ); /* Q28 */
1262 :
1263 : /* E_L = (float)sqrt((sfm_end[norm_ind+1] - sfm_start[norm_ind])/E_L); */
1264 708 : L_E = Mult_32_16( L_E, inv_tbl_fx[band_size] ); /* Q28 (28+15+1-16) */
1265 : /* To avoid overflow in Isqrt() */
1266 708 : if ( L_E == 0 )
1267 : {
1268 0 : L_E = L_deposit_l( 1 );
1269 : }
1270 708 : L_E = Isqrt( L_E ); /* Q17 (31-28/2) */
1271 :
1272 : /* normq = 0.1f*dicn[norm[norm_ind-1]] + 0.8f*dicn[norm[norm_ind]] + 0.1f*dicn[norm[norm_ind+1]]; */
1273 : /* tmp_norm = 0.1f*dicn[norm[norm_ind]] + 0.8f*dicn[norm[norm_ind+1]] + 0.1f*dicn[norm[norm_ind+2]]; */
1274 708 : L_tmp0 = L_add( dicn_fx[norm[norm_ind]], 0 ); /*Q14*/
1275 708 : L_tmp1 = L_add( dicn_fx[norm[norm_ind + 1]], 0 ); /*Q14*/
1276 708 : L_normq = Madd_32_16( Madd_32_16( Mult_32_16( L_tmp0, 26214 /* Q15, 0.8f */ ), dicn_fx[norm[norm_ind - 1]], 3277 /* Q15, 0.1f */ ), L_tmp1, 3277 /* Q15, 0.1f */ ); /* Q14 (14+15+1-16) */
1277 708 : move16();
1278 708 : L_tmp_norm = Madd_32_16( Madd_32_16( Mult_32_16( L_tmp1, 26214 /* Q15, 0.8f */ ), dicn_fx[norm[norm_ind + 2]], 3277 /* Q15, 0.1f */ ), L_tmp0, 3277 /* Q15, 0.1f */ ); /* Q14 (14+15+1-16) */
1279 708 : move16();
1280 :
1281 708 : istart = sfm_start[norm_ind];
1282 708 : move16();
1283 : /* iend = istart + sfm_len[norm_ind]/2; */
1284 708 : iend = 240;
1285 708 : move16();
1286 :
1287 708 : noise_mix_fx( &coeff_fine[-offset], L_E, L_normq, bwe_seed, istart, iend, noise_level[0], L_coeff_out, qin, qout );
1288 :
1289 708 : j = 0;
1290 708 : move16();
1291 : /* N = sfm_len[norm_ind]/2+sfm_len[norm_ind+1]/2-1; */
1292 708 : N = 31;
1293 708 : move16();
1294 708 : j_N = N;
1295 708 : move16();
1296 :
1297 708 : istart = iend;
1298 708 : move16();
1299 : /* iend = sfm_start[norm_ind+1] + sfm_len[norm_ind+1]/2; */
1300 708 : iend = 272;
1301 708 : move16();
1302 :
1303 : /* special case that is not handled by noise_mix_fx() */
1304 708 : n_c = sub( MAX_16, noise_level[0] ); /* Q15 */
1305 23364 : FOR( i = istart; i < iend; i++ )
1306 : {
1307 : /* coeff_out[i] = ((float)(N-j)/N*normq + (float)j/N*tmp_norm)*((1.0f - noise_level[i/bwe_noise_th])*coeff_fine[i-offset]*E_L + noise_level[i/bwe_noise_th]*own_random(bwe_seed)/32768.0f); */
1308 22656 : L_tmp1 = Madd_32_16( Mult_32_16( L_normq, inv_N_fx[j_N] ), L_tmp_norm, inv_N_fx[j] ); /* Q14 (14+15+1-16) */
1309 22656 : j = add( j, 1 );
1310 22656 : j_N = sub( j_N, 1 );
1311 :
1312 22656 : Mpy_32_16_ss( L_E, coeff_fine[i - offset], &L_tmp0, &lsb ); /* Qin+2 (17+qin+1-16) */
1313 22656 : Mpy_32_16_ss( L_tmp0, n_c, &L_tmp0, &lsb ); /* Qin+2-15 (qin+2+15+1-16) */
1314 :
1315 22656 : IF( L_tmp0 != 0 )
1316 : {
1317 : /* Normalize with 1 bit headroom for addition */
1318 22644 : tmp = sub( 30, add( qin, 2 ) ); /* Assuming fixed Q values */
1319 22644 : tmp = s_min( norm_l( L_tmp0 ), tmp );
1320 22644 : tmp = sub( tmp, 1 );
1321 :
1322 22644 : L_tmp0 = L_add( L_shl( L_tmp0, tmp ), L_shr( lsb, sub( 16, tmp ) ) ); /* Qin+2+tmp */
1323 :
1324 22644 : L_tmp0 = L_add( L_tmp0, L_shr( L_mult0( noise_level[0], Random( bwe_seed ) ), sub( sub( 30, add( qin, 2 ) ), tmp ) ) ); /* Qin+2+tmp */
1325 22644 : tmp = round_fx( L_shl( L_tmp0, sub( sub( 27, add( qin, 2 ) ), tmp ) ) ); /* Q11 (Qin+2+tmp+27-qin-2-tmp-16) */
1326 :
1327 22644 : Mpy_32_16_ss( L_tmp1, tmp, &L_tmp0, &lsb ); /* Q10 (14+11+1-16) */
1328 22644 : L_coeff_out[i] = L_add( L_shl( L_tmp0, sub( qout, 10 ) ), L_shr( lsb, add( 10, sub( 16, qout ) ) ) ); /*Qout*/
1329 22644 : move32();
1330 : }
1331 : ELSE
1332 : {
1333 12 : L_tmp0 = L_mult0( noise_level[0], Random( bwe_seed ) ); /* Q30 (15+15) */
1334 12 : tmp = round_fx( L_tmp0 ); /* Q14 (30-16) */
1335 12 : Mpy_32_16_ss( L_tmp1, tmp, &L_tmp0, &lsb ); /* Q13 (14+14+1-16) */
1336 12 : L_coeff_out[i] = L_shr( L_tmp0, sub( 13, qout ) ); /*Qout*/
1337 12 : move32();
1338 : }
1339 : }
1340 :
1341 708 : istart = iend;
1342 708 : move16();
1343 708 : iend = sfm_end[norm_ind + 1];
1344 708 : move16();
1345 :
1346 708 : noise_mix_fx( &coeff_fine[-offset], L_E, L_tmp_norm, bwe_seed, istart, iend, noise_level[0], L_coeff_out, qin, qout );
1347 :
1348 708 : norm_ind = add( norm_ind, 2 );
1349 : }
1350 :
1351 11413 : FOR( ; norm_ind < num_sfm; norm_ind++ )
1352 : {
1353 10184 : IF( R[norm_ind] == 0 )
1354 : {
1355 9929 : peak_band = 0;
1356 9929 : move16();
1357 :
1358 582457 : FOR( i = sfm_start[norm_ind]; i < sfm_end[norm_ind]; i++ )
1359 : {
1360 572528 : if ( bwe_peaks[i] )
1361 : {
1362 30962 : peak_band = 1;
1363 30962 : move16();
1364 : }
1365 : }
1366 :
1367 9929 : istart = sfm_start[norm_ind];
1368 9929 : move16();
1369 9929 : iend = sfm_end[norm_ind];
1370 9929 : move16();
1371 :
1372 9929 : last_norm_ind = sub( num_sfm, 1 );
1373 9929 : test();
1374 9929 : test();
1375 9929 : IF( EQ_16( peak_band, 1 ) && GT_16( norm_ind, add( last_sfm, 1 ) ) && LT_16( norm_ind, last_norm_ind ) )
1376 : {
1377 7713 : istart = sub( istart, shr( sfm_len[norm_ind - 1], 1 ) );
1378 7713 : iend = add( iend, shr( sfm_len[norm_ind + 1], 1 ) );
1379 : }
1380 :
1381 9929 : tmp = 1;
1382 9929 : move16();
1383 1006873 : FOR( i = istart; i < iend; i++ )
1384 : {
1385 996944 : tmp2 = abs_s( coeff_fine[i - offset] );
1386 996944 : tmp = s_max( tmp, tmp2 );
1387 : }
1388 9929 : band_size = sub( iend, istart );
1389 : /* Headroom for square and accumulate */
1390 9929 : shift = sub( norm_s( tmp ), sqac_headroom_fx[band_size] );
1391 :
1392 9929 : L_E = 1L;
1393 9929 : move32();
1394 1006873 : FOR( i = istart; i < iend; i++ )
1395 : {
1396 : /* E_L += coeff_fine[i-offset] * coeff_fine[i-offset]; */
1397 996944 : coeff_s[i] = shl( coeff_fine[i - offset], shift );
1398 996944 : move16(); /* Q15 + shift */
1399 996944 : L_E = L_mac0( L_E, coeff_s[i], coeff_s[i] ); /* Q2*(15 + shift) */
1400 : }
1401 9929 : power_shift = shl( shift, 1 );
1402 :
1403 9929 : L_E = L_shr( L_E, sub( power_shift, sub( 28, imult1616( 2, qin ) ) ) ); /* Q28 */
1404 :
1405 : /* E_L = (float)sqrt((iend - istart)/E_L); */
1406 9929 : L_E = Mult_32_16( L_E, inv_tbl_fx[band_size] ); /* Q28 (28+15+1-16) */
1407 : /* To avoid overflow in Isqrt() */
1408 9929 : if ( L_E == 0 )
1409 : {
1410 0 : L_E = 1L;
1411 0 : move32();
1412 : }
1413 9929 : L_E = Isqrt( L_E ); /* Q17 (31-28/2) */
1414 :
1415 9929 : IF( peak_band )
1416 : {
1417 9395 : IF( GT_16( add( norm_ind, 2 ), num_sfm ) )
1418 : {
1419 : /* normq = 0.15f*dicn[norm[norm_ind-1]] + 0.85f*dicn[norm[norm_ind]]; */
1420 1220 : L_normq = Madd_32_16( Mult_32_16( dicn_fx[norm[norm_ind]], 27853 /* Q15, 0.85f */ ), dicn_fx[norm[norm_ind - 1]], 4915 /* Q15, 0.1f */ ); /* Q14 (14+15+1-16) */
1421 1220 : move16();
1422 1220 : move16();
1423 : }
1424 : ELSE
1425 : {
1426 : /* normq = 0.1f*dicn[norm[norm_ind-1]] + 0.8f*dicn[norm[norm_ind]] + 0.1f*dicn[norm[norm_ind+1]]; */
1427 8175 : L_normq = Madd_32_16( Madd_32_16( Mult_32_16( dicn_fx[norm[norm_ind]], 26214 /* Q15, 0.8f */ ), dicn_fx[norm[norm_ind + 1]], 3277 /* Q15, 0.1f */ ), dicn_fx[norm[norm_ind - 1]], 3277 /* Q15, 0.1f */ ); /* Q14 (14+15+1-16) */
1428 8175 : move16();
1429 8175 : move16();
1430 8175 : move16();
1431 : }
1432 : }
1433 : ELSE
1434 : {
1435 534 : low = norm_ind;
1436 534 : move16();
1437 534 : high = s_min( add( norm_ind, 1 ), last_norm_ind );
1438 534 : move16();
1439 534 : sel_norm = norm[norm_ind - 1]; /*Q0*/
1440 534 : move16();
1441 1593 : FOR( j = low; j <= high; j++ )
1442 : {
1443 1059 : if ( GT_16( norm[j], sel_norm ) )
1444 : {
1445 532 : sel_norm = norm[j]; /*Q0*/
1446 532 : move16();
1447 : }
1448 : }
1449 534 : L_normq = dicn_fx[sel_norm]; /*Q14*/
1450 534 : move16();
1451 : }
1452 :
1453 9929 : iend = s_min( sfm_end[norm_ind], bwe_noise_th );
1454 9929 : move16();
1455 9929 : IF( GT_16( iend, sfm_start[norm_ind] ) )
1456 : {
1457 5712 : noise_mix_fx( &coeff_fine[-offset], L_E, L_normq, bwe_seed, sfm_start[norm_ind], iend, noise_level[0], L_coeff_out, qin, qout );
1458 : }
1459 : ELSE
1460 : {
1461 4217 : iend = sfm_end[norm_ind];
1462 4217 : move16();
1463 4217 : noise_mix_fx( &coeff_fine[-offset], L_E, L_normq, bwe_seed, sfm_start[norm_ind], iend, noise_level[1], L_coeff_out, qin, qout );
1464 : }
1465 : /* Noisemix up to threshold done */
1466 9929 : IF( EQ_16( iend, bwe_noise_th ) )
1467 : {
1468 1229 : noise_mix_fx( &coeff_fine[-offset], L_E, L_normq, bwe_seed, iend, sfm_end[norm_ind], noise_level[1], L_coeff_out, qin, qout );
1469 : }
1470 : }
1471 : ELSE /* R[norm_ind] > 0 */
1472 : {
1473 11823 : FOR( i = sfm_start[norm_ind]; i < sfm_end[norm_ind]; i++ )
1474 : {
1475 11568 : L_coeff_out[i] = L_coeff[i]; /* Scaling already applied Q12*/
1476 11568 : move32();
1477 : }
1478 : }
1479 : }
1480 :
1481 1229 : prev_noise_level[0] = noise_level[0]; /*Q15*/
1482 1229 : move16();
1483 1229 : prev_noise_level[1] = noise_level[1]; /*Q15*/
1484 1229 : move16();
1485 1229 : L_src = &L_coeff_out[( sfm_end[last_sfm] + L_HARMONIC_EXC - START_EXC )]; /* Address initialization Qout*/
1486 1229 : L_dst = L_src - 1; /* Address computation Qout*/
1487 :
1488 20893 : FOR( i = 0; i < 16; i++ )
1489 : {
1490 19664 : *L_src = Mult_32_16( *L_src, hvq_bwe_fac_fx[i] ); /* Qout (Qout+15+1-16) */
1491 19664 : L_src++; /* Qout (Qout+15+1-16) */
1492 19664 : move32();
1493 19664 : *L_dst = Mult_32_16( *L_dst, hvq_bwe_fac_fx[i] ); /* Qout (Qout+15+1-16) */
1494 19664 : L_dst--; /* Qout (Qout+15+1-16) */
1495 19664 : move32();
1496 : }
1497 :
1498 1229 : return;
1499 : }
1500 :
1501 : /*-------------------------------------------------------------------*
1502 : * hvq_concat_bands_fx()
1503 : *
1504 : * Compute the band limits for concatenated bands for PVQ target signal in HVQ
1505 : *--------------------------------------------------------------------------*/
1506 2692 : void hvq_concat_bands_fx(
1507 : const Word16 pvq_bands, /* i : Number of bands in concatenated PVQ target Q0*/
1508 : const Word16 *sel_bnds, /* i : Array of selected high bands Q0*/
1509 : const Word16 n_sel_bnds, /* i : Number of selected high bands Q0*/
1510 : Word16 *hvq_band_start, /* i : Band start indices Q0*/
1511 : Word16 *hvq_band_width, /* i : Band widths Q0*/
1512 : Word16 *hvq_band_end /* i : Band end indices Q0*/
1513 : )
1514 : {
1515 : Word16 k, k_1;
1516 : const Word16 *pSelBnds;
1517 :
1518 2692 : pSelBnds = sel_bnds;
1519 7972 : FOR( k = 0; k < pvq_bands; k++ )
1520 : {
1521 :
1522 5280 : IF( GE_16( k, sub( pvq_bands, n_sel_bnds ) ) )
1523 : {
1524 691 : k_1 = sub( k, 1 );
1525 691 : hvq_band_start[k] = hvq_band_end[k_1]; /*Q0*/
1526 691 : move16();
1527 691 : hvq_band_width[k] = band_len_harm[*pSelBnds++]; /*Q0*/
1528 691 : move16();
1529 691 : move16();
1530 691 : hvq_band_end[k] = add( hvq_band_end[k_1], hvq_band_width[k] ); /*Q0*/
1531 691 : move16();
1532 : }
1533 : ELSE
1534 : {
1535 4589 : hvq_band_start[k] = extract_l( L_mult0( k, HVQ_PVQ_COEFS ) ); /*Q0*/
1536 4589 : move16();
1537 4589 : hvq_band_width[k] = HVQ_PVQ_COEFS; /*Q0*/
1538 4589 : move16();
1539 4589 : hvq_band_end[k] = add( hvq_band_start[k], HVQ_PVQ_COEFS ); /*Q0*/
1540 4589 : move16();
1541 : }
1542 : }
1543 :
1544 2692 : return;
1545 : }
1546 : /*--------------------------------------------------------------------------*
1547 : * noise_mix_fx()
1548 : *--------------------------------------------------------------------------*/
1549 :
1550 12574 : void noise_mix_fx(
1551 : const Word16 *coeff_fine, /* i : normalized fine structure spectrum Qin */
1552 : const Word32 L_E, /* i : normalization factor Q17 */
1553 : const Word32 L_normq, /* i : quantized norm Q14 */
1554 : Word16 *seed, /* i/o: random seed Q0 */
1555 : const Word16 istart, /* i : start coefficient Q0 */
1556 : const Word16 iend, /* i : end coefficient Q0 */
1557 : const Word16 noise_level, /* i : noise_level Q0 */
1558 : Word32 *L_coeff_out, /* o : noise mixed spectrum Qout */
1559 : const Word16 qin,
1560 : const Word16 qout )
1561 : {
1562 : Word16 i, tmp, n_c;
1563 : Word32 L_tmp0;
1564 : UWord16 lsb;
1565 :
1566 12574 : n_c = sub( MAX_16, noise_level ); /* Q15 */
1567 607758 : FOR( i = istart; i < iend; i++ )
1568 : {
1569 : /* L_coeff_out[i] = ((1.0f - noise_level)*coeff_fine[i]*L_E + noise_level*own_random(seed)/32768.0f)*normq; */
1570 595184 : Mpy_32_16_ss( L_E, coeff_fine[i], &L_tmp0, &lsb ); /* Qin+qL_E-15 (qL_E+qin+1-16) */
1571 595184 : Mpy_32_16_ss( L_tmp0, n_c, &L_tmp0, &lsb ); /* Qin+qL_E-15 (qin+qL_E-15+15+1-16) */
1572 :
1573 595184 : IF( L_tmp0 != 0 )
1574 : {
1575 : /* Normalize with 1 bit headroom for addition */
1576 523086 : tmp = sub( 30, add( qin, 2 ) ); /* Assuming fixed Q values */
1577 523086 : tmp = s_min( norm_l( L_tmp0 ), tmp );
1578 523086 : tmp = sub( tmp, 1 );
1579 :
1580 523086 : L_tmp0 = L_add( L_shl( L_tmp0, tmp ), L_shr( lsb, sub( 16, tmp ) ) ); /* Qin+2+tmp */
1581 523086 : L_tmp0 = L_add( L_tmp0, L_shr( L_mult0( noise_level, Random( seed ) ), sub( sub( 30, add( qin, 2 ) ), tmp ) ) ); /* Qin+2+tmp */
1582 :
1583 523086 : tmp = round_fx( L_shl( L_tmp0, sub( sub( 27, add( qin, 2 ) ), tmp ) ) ); /* Q11 (Qin+2+tmp+27-qin-2-tmp-16) */
1584 523086 : Mpy_32_16_ss( L_normq, tmp, &L_tmp0, &lsb ); /* Q10 (14+11+1-16) */
1585 523086 : L_coeff_out[i] = L_add( L_shl( L_tmp0, sub( qout, 10 ) ), L_shr( lsb, add( 10, sub( 16, qout ) ) ) ); /* Qout (10+qout-10) */
1586 523086 : move32();
1587 : }
1588 : ELSE
1589 : {
1590 72098 : L_tmp0 = L_mult0( noise_level, Random( seed ) ); /* Q30 (15+15) */
1591 72098 : tmp = round_fx( L_tmp0 ); /* Q14 (30-16) */
1592 72098 : Mpy_32_16_ss( L_normq, tmp, &L_tmp0, &lsb ); /* Q13 (14+14+1-16) */
1593 72098 : L_coeff_out[i] = L_shr( L_tmp0, sub( 13, qout ) ); /* Qout (13-(13-qout)) */
1594 72098 : move32();
1595 : }
1596 : }
1597 12574 : }
1598 :
1599 :
1600 : /*--------------------------------------------------------------------------*
1601 : * hq_generic_fine_fx()
1602 : *
1603 : * Prepare HQ GENERIC HF fine structure
1604 : *--------------------------------------------------------------------------*/
1605 2789 : void hq_generic_fine_fx(
1606 : Word16 *coeff, /* i : coded/noisefilled normalized spectrum Q12*/
1607 : const Word16 last_sfm, /* i : Last coded band Q0*/
1608 : const Word16 *sfm_start, /* i : Subband start coefficient Q0*/
1609 : const Word16 *sfm_end, /* i : Subband end coefficient Q0*/
1610 : Word16 *bwe_seed, /* i/o: random seed for generating BWE input Q0*/
1611 : Word16 *coeff_out1 /* o : HQ GENERIC input Q12*/
1612 : )
1613 : {
1614 : Word16 sfm;
1615 : Word16 i;
1616 :
1617 78103 : FOR( sfm = 0; sfm <= last_sfm; sfm++ )
1618 : {
1619 990370 : FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
1620 : {
1621 915056 : IF( coeff[i] == 0 )
1622 : {
1623 522084 : coeff_out1[i] = -2048; /*Q12*/
1624 522084 : move16();
1625 522084 : if ( Random( bwe_seed ) > 0 )
1626 : {
1627 261652 : coeff_out1[i] = 2048; /*Q12*/
1628 261652 : move16();
1629 : }
1630 : }
1631 : ELSE
1632 : {
1633 392972 : coeff_out1[i] = coeff[i]; /*Q12*/
1634 392972 : move16();
1635 : }
1636 : }
1637 : }
1638 :
1639 2789 : return;
1640 : }
1641 :
1642 : /*--------------------------------------------------------------------------*
1643 : * overlap_hq_bwe_fx()
1644 : *
1645 : * Overlapping at the boundary between HQ core and BWE
1646 : *--------------------------------------------------------------------------*/
1647 2789 : static void overlap_hq_bwe_fx(
1648 : const Word32 *hq_swb_overlap_buf, /* i : spectrum from HQ core Q12*/
1649 : Word32 *coeff_out, /* i/o: spectrum from BWE, overlapped output Q12*/
1650 : const Word16 n_swb_overlap_offset, /* i : starting offset of overlapping Q0*/
1651 : const Word16 n_swb_overlap, /* i : length of overlapping Q0*/
1652 : const Word16 *R, /*Q0*/
1653 : const Word16 num_env_bands, /*Q0*/
1654 : const Word16 num_sfm, /*Q0*/
1655 : const Word16 *sfm_end /*Q0*/ )
1656 : {
1657 : Word16 i;
1658 : Word16 weighting;
1659 : Word16 step;
1660 : Word16 exp, tmp, n_band;
1661 :
1662 2789 : IF( R[( num_env_bands - 1 )] != 0 )
1663 : {
1664 1518 : Copy32( hq_swb_overlap_buf, &coeff_out[n_swb_overlap_offset], n_swb_overlap ); /*Q12*/
1665 : }
1666 : ELSE
1667 : {
1668 1271 : exp = norm_s( n_swb_overlap );
1669 1271 : tmp = div_s( 16384, shl( n_swb_overlap, exp ) ); /*15 + 14 - exp */
1670 1271 : tmp = shr( tmp, sub( 14, exp ) ); /*15 */
1671 1271 : step = mult_r( tmp, 32767 ); /*15 */
1672 1271 : weighting = 32767;
1673 1271 : move16();
1674 11439 : FOR( i = 0; i < n_swb_overlap; i++ )
1675 : {
1676 10168 : coeff_out[( n_swb_overlap_offset + i )] = L_add( coeff_out[( n_swb_overlap_offset + i )],
1677 10168 : Mult_32_16( L_sub( hq_swb_overlap_buf[i], coeff_out[( n_swb_overlap_offset + i )] ), weighting ) ); /*Q12*/
1678 10168 : move32();
1679 10168 : weighting = sub( weighting, step );
1680 : }
1681 : }
1682 :
1683 46607 : FOR( n_band = num_env_bands; n_band < num_sfm; n_band++ )
1684 : {
1685 43818 : IF( R[n_band] != 0 )
1686 : {
1687 275 : FOR( i = sfm_end[( n_band - 1 )]; i < sfm_end[n_band]; ++i )
1688 : {
1689 264 : coeff_out[i] = hq_swb_overlap_buf[( i - n_swb_overlap_offset )]; /*Q12*/
1690 264 : move32();
1691 : }
1692 : }
1693 : }
1694 2789 : return;
1695 : }
1696 :
1697 : /*--------------------------------------------------------------------------*
1698 : * map_hq_generic_fenv_norm()
1699 : *
1700 : * mapping high frequency envelope to high band norm
1701 : *--------------------------------------------------------------------------*/
1702 5626 : void map_hq_generic_fenv_norm_fx(
1703 : const Word16 hqswb_clas, /*Q0*/
1704 : const Word16 *hq_generic_fenv, /* Q1, frequency-domain BWE envelope */
1705 : Word16 *ynrm, /*Q0*/
1706 : Word16 *normqlg2, /*Q0*/
1707 : const Word16 num_env_bands, /*Q0*/
1708 : const Word16 nb_sfm, /*Q0*/
1709 : const Word16 hq_generic_offset /*Q0*/ )
1710 : {
1711 : Word32 env_fl[17]; /*Q8 */
1712 : Word16 i;
1713 :
1714 5626 : set32_fx( env_fl, 0, 17 );
1715 :
1716 5626 : IF( EQ_16( hq_generic_offset, 144 ) )
1717 : {
1718 0 : env_fl[0] = L_shl( hq_generic_fenv[1], 7 ); /*Q8*/
1719 0 : move32();
1720 0 : env_fl[1] = L_add( L_mult0( hq_generic_fenv[2], 85 ), L_mult0( hq_generic_fenv[3], 43 ) ); /*Q8*/
1721 0 : move32();
1722 0 : env_fl[2] = L_add( L_mult0( hq_generic_fenv[3], 85 ), L_mult0( hq_generic_fenv[4], 43 ) ); /*Q8*/
1723 0 : move32();
1724 0 : env_fl[3] = L_add( L_mult0( hq_generic_fenv[4], 43 ), L_mult0( hq_generic_fenv[5], 85 ) ); /*Q8*/
1725 0 : move32();
1726 0 : env_fl[4] = L_add( L_mult0( hq_generic_fenv[5], 43 ), L_mult0( hq_generic_fenv[6], 85 ) ); /*Q8*/
1727 0 : move32();
1728 0 : env_fl[5] = L_shl( hq_generic_fenv[7], 7 ); /*Q8*/
1729 0 : move32();
1730 0 : env_fl[6] = L_add( L_mult0( hq_generic_fenv[8], 96 ), L_mult0( hq_generic_fenv[9], 32 ) ); /*Q8*/
1731 0 : move32();
1732 0 : env_fl[7] = L_add( L_mult0( hq_generic_fenv[9], 96 ), L_mult0( hq_generic_fenv[10], 32 ) ); /*Q8*/
1733 0 : move32();
1734 0 : env_fl[8] = L_add( L_mult0( hq_generic_fenv[10], 32 ), L_mult0( hq_generic_fenv[11], 96 ) ); /*Q8*/
1735 0 : move32();
1736 : }
1737 : ELSE
1738 : {
1739 5626 : env_fl[0] = L_add( L_mult0( hq_generic_fenv[0], 43 ), L_mult0( hq_generic_fenv[1], 85 ) ); /*Q8*/
1740 5626 : move32();
1741 5626 : env_fl[1] = L_add( L_mult0( hq_generic_fenv[1], 43 ), L_mult0( hq_generic_fenv[2], 85 ) ); /*Q8*/
1742 5626 : move32();
1743 5626 : env_fl[2] = L_shl( hq_generic_fenv[3], 7 ); /*Q8*/
1744 5626 : move32();
1745 5626 : env_fl[3] = L_add( L_mult0( hq_generic_fenv[4], 85 ), L_mult0( hq_generic_fenv[5], 43 ) ); /*Q8*/
1746 5626 : move32();
1747 5626 : env_fl[4] = L_add( L_mult0( hq_generic_fenv[5], 85 ), L_mult0( hq_generic_fenv[6], 43 ) ); /*Q8*/
1748 5626 : move32();
1749 5626 : env_fl[5] = L_add( L_mult0( hq_generic_fenv[6], 43 ), L_mult0( hq_generic_fenv[7], 85 ) ); /*Q8*/
1750 5626 : move32();
1751 5626 : env_fl[6] = L_add( L_mult0( hq_generic_fenv[7], 43 ), L_mult0( hq_generic_fenv[8], 85 ) ); /*Q8*/
1752 5626 : move32();
1753 5626 : env_fl[7] = L_add( L_mult0( hq_generic_fenv[8], 43 ), L_mult0( hq_generic_fenv[9], 85 ) ); /*Q8*/
1754 5626 : move32();
1755 5626 : env_fl[8] = L_add( L_mult0( hq_generic_fenv[9], 43 ), L_mult0( hq_generic_fenv[10], 85 ) ); /*Q8*/
1756 5626 : move32();
1757 5626 : env_fl[9] = L_add( L_mult0( hq_generic_fenv[10], 32 ), L_mult0( hq_generic_fenv[11], 96 ) ); /*Q8*/
1758 5626 : move32();
1759 5626 : env_fl[10] = L_shl( hq_generic_fenv[12], 7 ); /*Q8*/
1760 5626 : move32();
1761 5626 : env_fl[11] = L_shl( hq_generic_fenv[13], 7 ); /*Q8*/
1762 5626 : move32();
1763 : }
1764 :
1765 5626 : IF( EQ_16( hqswb_clas, HQ_GEN_FB ) )
1766 : {
1767 4275 : IF( EQ_16( hq_generic_offset, 144 ) )
1768 : {
1769 0 : env_fl[9] = L_shl( hq_generic_fenv[12], 7 ); /*Q8*/
1770 0 : move32();
1771 0 : env_fl[10] = L_add( L_mult0( hq_generic_fenv[12], 32 ), L_mult0( hq_generic_fenv[13], 96 ) ); /*Q8*/
1772 0 : move32();
1773 0 : env_fl[11] = L_add( L_mult0( hq_generic_fenv[13], 64 ), L_mult0( hq_generic_fenv[14], 64 ) ); /*Q8*/
1774 0 : move32();
1775 0 : env_fl[12] = L_shl( hq_generic_fenv[12], 7 ); /*Q8*/
1776 0 : move32();
1777 0 : env_fl[13] = env_fl[12]; /*Q8*/
1778 0 : move32();
1779 : }
1780 : ELSE
1781 : {
1782 4275 : env_fl[12] = L_shl( hq_generic_fenv[14], 7 ); /*Q8*/
1783 4275 : move32();
1784 4275 : env_fl[13] = L_add( L_mult0( hq_generic_fenv[14], 32 ), L_mult0( hq_generic_fenv[15], 96 ) ); /*Q8*/
1785 4275 : move32();
1786 4275 : env_fl[14] = L_add( L_mult0( hq_generic_fenv[15], 64 ), L_mult0( hq_generic_fenv[16], 64 ) ); /*Q8*/
1787 4275 : move32();
1788 4275 : env_fl[15] = L_shl( hq_generic_fenv[16], 7 ); /*Q8*/
1789 4275 : move32();
1790 4275 : env_fl[16] = env_fl[15]; /*Q8*/
1791 4275 : move32();
1792 : }
1793 : }
1794 :
1795 5626 : logqnorm_2_fx( env_fl, 40, num_env_bands, nb_sfm, ynrm + num_env_bands, normqlg2 + num_env_bands, thren_fx );
1796 :
1797 94513 : FOR( i = num_env_bands; i < nb_sfm; ++i )
1798 : {
1799 88887 : normqlg2[i] = dicnlg2[s_min( add( ynrm[i], 10 ), 39 )]; /*Q0*/
1800 88887 : move16();
1801 : }
1802 5626 : return;
1803 : }
1804 :
1805 4 : static void update_rsubband_fx( const Word16 nb_sfm, /*Q0*/
1806 : Word16 *Rsubband, /* Q3 */
1807 : Word16 b_add_bits_denv /*Q0*/ )
1808 : {
1809 : Word16 i;
1810 :
1811 : /* updating bit allocation */
1812 8 : WHILE( b_add_bits_denv > 0 )
1813 : {
1814 4 : i = sub( nb_sfm, 1 );
1815 4 : test();
1816 76 : WHILE( b_add_bits_denv > 0 && i >= 0 )
1817 : {
1818 72 : IF( GT_16( Rsubband[i], 24 ) )
1819 : {
1820 40 : Rsubband[i] = sub( Rsubband[i], 8 ); /*Q3*/
1821 40 : move16();
1822 40 : b_add_bits_denv = sub( b_add_bits_denv, 1 ); /*Q0*/
1823 : }
1824 72 : i = sub( i, 1 );
1825 : }
1826 : }
1827 :
1828 4 : return;
1829 : }
1830 :
1831 2789 : Word16 get_nor_delta_hf_fx(
1832 : Decoder_State *st,
1833 : Word16 *ynrm, /*Q0*/
1834 : Word16 *Rsubband, /* Q3 */
1835 : const Word16 num_env_bands, /*Q0*/
1836 : const Word16 nb_sfm, /*Q0*/
1837 : const Word16 core_sfm /*Q0*/ )
1838 : {
1839 : Word16 i;
1840 : Word16 delta, bitsforDelta, add_bits_denv;
1841 :
1842 2789 : add_bits_denv = 0;
1843 2789 : move16();
1844 2789 : IF( GE_16( core_sfm, num_env_bands ) )
1845 : {
1846 3 : bitsforDelta = (Word16) get_next_indice_fx( st, 2 ); /*Q0*/
1847 3 : bitsforDelta = add( bitsforDelta, 2 );
1848 3 : add_bits_denv = add( add_bits_denv, 2 );
1849 :
1850 39 : FOR( i = num_env_bands; i < nb_sfm; ++i )
1851 : {
1852 36 : IF( Rsubband[i] != 0 )
1853 : {
1854 11 : delta = (Word16) get_next_indice_fx( st, bitsforDelta ); /*Q0*/
1855 11 : ynrm[i] = add( ynrm[i], sub( delta, ( shl( 1, sub( bitsforDelta, 1 ) ) ) ) ); /*Q0*/
1856 11 : move16();
1857 :
1858 : /* safety check in case of bit errors */
1859 11 : test();
1860 11 : IF( ynrm[i] < 0 || GT_16( ynrm[i], 39 ) )
1861 : {
1862 0 : ynrm[i] = 39;
1863 0 : move16();
1864 0 : st->BER_detect = 1;
1865 0 : move16();
1866 : }
1867 : /*ynrm[i] += delta - (1<<(bitsforDelta-1));*/
1868 11 : add_bits_denv = add( add_bits_denv, bitsforDelta );
1869 : }
1870 : }
1871 3 : update_rsubband_fx( nb_sfm, Rsubband, add_bits_denv );
1872 : }
1873 2789 : return add_bits_denv;
1874 : }
1875 : /*-------------------------------------------------------------------*
1876 : * calc_nor_delta_hf()
1877 : *
1878 : *
1879 : *--------------------------------------------------------------------------*/
1880 2805 : Word16 calc_nor_delta_hf_ivas_fx(
1881 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
1882 : const Word32 *t_audio, /* i : transform-domain coefficients Qx*/
1883 : Word16 *ynrm, /* i/o: norm indices Q0*/
1884 : Word16 *Rsubband, /* i/o: sub-band bit allocation Q0*/
1885 : const Word16 num_env_bands, /* i : Number coded envelope bands Q0*/
1886 : const Word16 nb_sfm, /* i : Number of envelope bands Q0*/
1887 : const Word16 *sfmsize, /* i : band length Q0*/
1888 : const Word16 *sfm_start, /* i : Start index of bands Q0*/
1889 : const Word16 core_sfm /* i : index of the end band for core Q0*/
1890 : )
1891 : {
1892 : Word16 i;
1893 : Word16 ynrm_t[44], normqlg2_t[44];
1894 : Word16 delta, max_delta, min_delta, bitsforDelta, add_bits_denv;
1895 :
1896 2805 : max_delta = -100;
1897 2805 : move16();
1898 2805 : calc_norm_fx( t_audio, 12, ynrm_t, normqlg2_t, 0, nb_sfm, sfmsize, sfm_start );
1899 2805 : add_bits_denv = 0;
1900 2805 : move16();
1901 47490 : FOR( i = num_env_bands; i < nb_sfm; ++i )
1902 : {
1903 44685 : IF( Rsubband[i] != 0 )
1904 : {
1905 0 : delta = sub( ynrm_t[i], ynrm[i] ); /*Q0*/
1906 0 : IF( delta > 0 )
1907 : {
1908 0 : delta = add( delta, 1 ); /*Q0*/
1909 : }
1910 : ELSE
1911 : {
1912 0 : delta = negate( delta ); /*Q0*/
1913 : }
1914 0 : if ( GT_16( delta, max_delta ) )
1915 : {
1916 0 : max_delta = delta; /*Q0*/
1917 0 : move16();
1918 : }
1919 : }
1920 : }
1921 2805 : IF( GE_16( core_sfm, num_env_bands ) )
1922 : {
1923 0 : IF( LT_16( max_delta, 16 ) )
1924 : {
1925 0 : bitsforDelta = 2;
1926 0 : move16();
1927 0 : FOR( ; max_delta >= 2; max_delta >>= 1 )
1928 : {
1929 0 : bitsforDelta = add( bitsforDelta, 1 ); /*Q0*/
1930 : }
1931 : }
1932 : ELSE
1933 : {
1934 0 : bitsforDelta = 5;
1935 0 : move16();
1936 : }
1937 0 : max_delta = sub( shl( 1, sub( bitsforDelta, 1 ) ), 1 ); /*Q0*/
1938 0 : min_delta = negate( add( max_delta, 1 ) ); /*Q0*/
1939 :
1940 : /* updating norm & storing delta norm */
1941 0 : add_bits_denv = 2;
1942 0 : move16();
1943 0 : push_indice( hBstr, IND_DELTA_ENV_HQ, sub( bitsforDelta, 2 ), 2 );
1944 0 : FOR( i = num_env_bands; i < nb_sfm; ++i )
1945 : {
1946 0 : IF( Rsubband[i] != 0 )
1947 : {
1948 0 : delta = sub( ynrm_t[i], ynrm[i] );
1949 0 : IF( GT_16( delta, max_delta ) )
1950 : {
1951 0 : delta = max_delta; /*Q0*/
1952 0 : move16();
1953 : }
1954 0 : ELSE IF( LT_16( delta, min_delta ) )
1955 : {
1956 0 : delta = min_delta; /*Q0*/
1957 0 : move16();
1958 : }
1959 0 : push_indice( hBstr, IND_DELTA_ENV_HQ, delta - min_delta, bitsforDelta );
1960 0 : ynrm[i] = add( ynrm[i], delta ); /*Q0*/
1961 0 : move16();
1962 0 : add_bits_denv = add( add_bits_denv, bitsforDelta );
1963 : }
1964 : }
1965 :
1966 : /* updating bit allocation */
1967 0 : update_rsubband_fx( nb_sfm, Rsubband, add_bits_denv );
1968 : }
1969 2805 : return add_bits_denv;
1970 : }
1971 : /*-------------------------------------------------------------------*
1972 : * calc_nor_delta_hf()
1973 : *
1974 : *
1975 : *--------------------------------------------------------------------------*/
1976 32 : Word16 calc_nor_delta_hf_fx(
1977 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
1978 : const Word32 *t_audio, /* i : transform-domain coefficients Qx*/
1979 : Word16 *ynrm, /* i/o: norm indices Q0*/
1980 : Word16 *Rsubband, /* i/o: sub-band bit allocation Q0*/
1981 : const Word16 num_env_bands, /* i : Number coded envelope bands Q0*/
1982 : const Word16 nb_sfm, /* i : Number of envelope bands Q0*/
1983 : const Word16 *sfmsize, /* i : band length Q0*/
1984 : const Word16 *sfm_start, /* i : Start index of bands Q0*/
1985 : const Word16 core_sfm /* i : index of the end band for core Q0*/
1986 : )
1987 : {
1988 : Word16 i;
1989 : Word16 ynrm_t[44], normqlg2_t[44];
1990 : Word16 delta, max_delta, min_delta, bitsforDelta, add_bits_denv;
1991 :
1992 32 : max_delta = -100;
1993 32 : move16();
1994 32 : calc_norm_fx( t_audio, 12, ynrm_t, normqlg2_t, 0, nb_sfm, sfmsize, sfm_start );
1995 32 : add_bits_denv = 0;
1996 32 : move16();
1997 416 : FOR( i = num_env_bands; i < nb_sfm; ++i )
1998 : {
1999 384 : IF( Rsubband[i] != 0 )
2000 : {
2001 5 : delta = sub( ynrm_t[i], ynrm[i] );
2002 5 : IF( delta > 0 )
2003 : {
2004 0 : delta = add( delta, 1 ); /*Q0*/
2005 : }
2006 : ELSE
2007 : {
2008 5 : delta = negate( delta ); /*Q0*/
2009 : }
2010 5 : if ( GT_16( delta, max_delta ) )
2011 : {
2012 1 : max_delta = delta; /*Q0*/
2013 1 : move16();
2014 : }
2015 : }
2016 : }
2017 32 : IF( GE_16( core_sfm, num_env_bands ) )
2018 : {
2019 1 : IF( LT_16( max_delta, 16 ) )
2020 : {
2021 1 : bitsforDelta = 2;
2022 1 : move16();
2023 1 : FOR( ; max_delta >= 2; max_delta >>= 1 )
2024 : {
2025 0 : bitsforDelta = add( bitsforDelta, 1 ); /*Q0*/
2026 : }
2027 : }
2028 : ELSE
2029 : {
2030 0 : bitsforDelta = 5;
2031 0 : move16();
2032 : }
2033 1 : max_delta = sub( shl( 1, sub( bitsforDelta, 1 ) ), 1 ); /*Q0*/
2034 1 : min_delta = negate( add( max_delta, 1 ) ); /*Q0*/
2035 :
2036 : /* updating norm & storing delta norm */
2037 1 : add_bits_denv = 2;
2038 1 : move16();
2039 1 : push_indice( hBstr, IND_DELTA_ENV_HQ, sub( bitsforDelta, 2 ), 2 );
2040 13 : FOR( i = num_env_bands; i < nb_sfm; ++i )
2041 : {
2042 12 : IF( Rsubband[i] != 0 )
2043 : {
2044 5 : delta = sub( ynrm_t[i], ynrm[i] ); /*Q0*/
2045 5 : IF( GT_16( delta, max_delta ) )
2046 : {
2047 0 : delta = max_delta; /*Q0*/
2048 0 : move16();
2049 : }
2050 5 : ELSE IF( LT_16( delta, min_delta ) )
2051 : {
2052 0 : delta = min_delta; /*Q0*/
2053 0 : move16();
2054 : }
2055 5 : push_indice( hBstr, IND_DELTA_ENV_HQ, delta - min_delta, bitsforDelta );
2056 5 : ynrm[i] = add( ynrm[i], delta ); /*Q0*/
2057 5 : move16();
2058 5 : add_bits_denv = add( add_bits_denv, bitsforDelta );
2059 : }
2060 : }
2061 :
2062 : /* updating bit allocation */
2063 1 : update_rsubband_fx( nb_sfm, Rsubband, add_bits_denv );
2064 : }
2065 32 : return add_bits_denv;
2066 : }
2067 :
2068 :
2069 : /*-------------------------------------------------------------------*
2070 : * hq_bwe_fx()
2071 : *
2072 : * HQ GENERIC
2073 : *--------------------------------------------------------------------------*/
2074 46 : void hq_bwe_fx(
2075 : const Word16 HQ_mode, /* i : HQ mode Q0*/
2076 : Word32 *coeff_out1, /* i/o: BWE input & temporary buffer Q12*/
2077 : const Word16 *hq_generic_fenv, /* i : SWB frequency envelopes Q1*/
2078 : Word32 *coeff_out, /* o : SWB signal in MDCT domain Q12*/
2079 : const Word16 hq_generic_offset, /* i : frequency offset for representing hq generic Q0*/
2080 : Word16 *prev_L_swb_norm, /* i/o: last normalize length Q0*/
2081 : const Word16 hq_generic_exc_clas, /* i : hq generic hf excitation class Q0*/
2082 : const Word16 *sfm_end, /* i : End of bands Q0*/
2083 : const Word16 num_sfm, /* i : Number of bands Q0*/
2084 : const Word16 num_env_bands, /* i : Number of coded envelope bands Q0*/
2085 : const Word16 *R /* i : Bit allocation Q0*/
2086 : )
2087 : {
2088 : Word16 n_swb_overlap_offset, n_swb_overlap;
2089 : Word32 hq_swb_overlap_buf_fx[L_FRAME32k];
2090 :
2091 46 : n_swb_overlap_offset = add( swb_bwe_subband[0], hq_generic_offset );
2092 46 : n_swb_overlap = sub( sfm_end[( num_env_bands - 1 )], n_swb_overlap_offset ); /*Q0*/
2093 :
2094 :
2095 46 : Copy32( &coeff_out[n_swb_overlap_offset], hq_swb_overlap_buf_fx, sub( add( n_swb_overlap, sfm_end[( num_sfm - 1 )] ), sfm_end[( num_env_bands - 1 )] ) ); /*Q12*/
2096 :
2097 46 : hq_generic_decoding_fx( HQ_mode, coeff_out1, hq_generic_fenv, coeff_out, hq_generic_offset, prev_L_swb_norm, hq_generic_exc_clas, R );
2098 :
2099 46 : overlap_hq_bwe_fx( hq_swb_overlap_buf_fx, coeff_out, n_swb_overlap_offset, n_swb_overlap, R, num_env_bands, num_sfm, sfm_end );
2100 :
2101 46 : return;
2102 : }
2103 :
2104 2743 : void hq_bwe_ivas_fx(
2105 : const Word16 HQ_mode, /* i : HQ mode Q0*/
2106 : Word32 *coeff_out1, /* i/o: BWE input & temporary buffer Q12*/
2107 : const Word16 *hq_generic_fenv, /* i : SWB frequency envelopes Q1*/
2108 : Word32 *coeff_out, /* o : SWB signal in MDCT domain Q12*/
2109 : const Word16 hq_generic_offset, /* i : frequency offset for representing hq generic Q0*/
2110 : Word16 *prev_L_swb_norm, /* i/o: last normalize length Q0*/
2111 : const Word16 hq_generic_exc_clas, /* i : hq generic hf excitation class Q0*/
2112 : const Word16 *sfm_end, /* i : End of bands Q0*/
2113 : const Word16 num_sfm, /* i : Number of bands Q0*/
2114 : const Word16 num_env_bands, /* i : Number of coded envelope bands Q0*/
2115 : const Word16 *R /* i : Bit allocation Q0*/
2116 : )
2117 : {
2118 : Word16 n_swb_overlap_offset, n_swb_overlap;
2119 : Word32 hq_swb_overlap_buf_fx[L_FRAME32k];
2120 :
2121 2743 : n_swb_overlap_offset = add( swb_bwe_subband[0], hq_generic_offset );
2122 2743 : n_swb_overlap = sub( sfm_end[( num_env_bands - 1 )], n_swb_overlap_offset ); /*Q0*/
2123 :
2124 :
2125 2743 : Copy32( &coeff_out[n_swb_overlap_offset], hq_swb_overlap_buf_fx, sub( add( n_swb_overlap, sfm_end[( num_sfm - 1 )] ), sfm_end[( num_env_bands - 1 )] ) ); /*Q12*/
2126 :
2127 2743 : hq_generic_decoding_ivas_fx( HQ_mode, coeff_out1, hq_generic_fenv, coeff_out, hq_generic_offset, prev_L_swb_norm, hq_generic_exc_clas, R );
2128 :
2129 2743 : overlap_hq_bwe_fx( hq_swb_overlap_buf_fx, coeff_out, n_swb_overlap_offset, n_swb_overlap, R, num_env_bands, num_sfm, sfm_end );
2130 :
2131 2743 : return;
2132 : }
2133 :
2134 : /*--------------------------------------------------------------------------*
2135 : * hq_wb_nf_bwe()
2136 : *
2137 : * HQ WB noisefill and BWE
2138 : *--------------------------------------------------------------------------*/
2139 :
2140 476 : void hq_wb_nf_bwe_fx(
2141 : const Word16 *coeff_fx, /* i : coded/noisefilled normalized spectrum Q12*/
2142 : const Word16 is_transient, /*Q0*/
2143 : const Word16 prev_bfi, /* i : previous bad frame indicator Q0*/
2144 : const Word32 *L_normq_v, /*Q14*/
2145 : const Word16 num_sfm, /* i : Number of subbands Q0*/
2146 : const Word16 *sfm_start, /* i : Subband start coefficient Q0*/
2147 : const Word16 *sfm_end, /* i : Subband end coefficient Q0*/
2148 : const Word16 *sfmsize, /* i : Subband band width Q0*/
2149 : const Word16 last_sfm, /* i : last coded subband Q0*/
2150 : const Word16 *R, /* i : bit allocation Q0*/
2151 : const Word16 prev_is_transient, /* i : previous transient flag Q0*/
2152 : Word32 *prev_normq_fx, /* i/o: previous norms Q14*/
2153 : Word32 *prev_env_fx, /* i/o: previous noise envelopes prev_env_Q*/
2154 : Word16 *bwe_seed, /* i/o: random seed for generating BWE input Q0*/
2155 : Word32 *prev_coeff_out_fx, /* i/o: decoded spectrum in previous frame Q12*/
2156 : Word16 *prev_R, /* i/o: bit allocation info. in previous frame Q0*/
2157 : Word32 *L_coeff_out, /* o : coded/noisefilled spectrum Q12*/
2158 : Word16 *prev_env_Q )
2159 : {
2160 : Word16 i;
2161 : Word16 sfm;
2162 : Word16 total_bit;
2163 : Word16 num;
2164 : Word32 env_fx, peak_fx, fabs_coeff_out_fx, min_coef_fx;
2165 476 : Word32 L_tmp1, L_tmp2 = 0, L_tmp3, L_tmp4;
2166 476 : move32();
2167 476 : Word16 tmp1, exp = 0, exp1, exp2, exp3, harm_para_fx, sharp_fx, step_fx, alfa_fx = 4096;
2168 476 : move16();
2169 476 : move16();
2170 : Word32 avrg_norm_fx, prev_avrg_norm_fx;
2171 : Word16 bitalloc_var_fx;
2172 : Word16 tmp;
2173 : Word32 L_tmp;
2174 : Word32 mean_fx;
2175 :
2176 476 : IF( is_transient == 0 )
2177 : {
2178 465 : IF( EQ_16( prev_bfi, 1 ) )
2179 : {
2180 4 : Copy32( L_normq_v, prev_normq_fx, SFM_N_WB ); /*Q14*/
2181 : }
2182 :
2183 : /* the variance of bit allocation */
2184 465 : total_bit = 0;
2185 465 : bitalloc_var_fx = 0;
2186 465 : move16();
2187 465 : move16();
2188 :
2189 8117 : FOR( sfm = 8; sfm <= last_sfm; sfm++ )
2190 : {
2191 7652 : tmp = abs_s( sub( R[sfm], R[( sfm - 1 )] ) ); /*Q0*/
2192 7652 : bitalloc_var_fx = add( bitalloc_var_fx, tmp );
2193 7652 : total_bit = add( total_bit, R[sfm] ); /*Q0*/
2194 : }
2195 465 : test();
2196 465 : IF( GT_16( last_sfm, 8 ) && total_bit > 0 )
2197 : {
2198 458 : exp = norm_s( total_bit );
2199 458 : tmp = shl( total_bit, exp ); /*Q(exp) */
2200 458 : tmp = div_s( 16384, tmp ); /*Q(15+14-exp) */
2201 458 : L_tmp = L_mult( tmp, bitalloc_var_fx ); /*Q(29-exp+1) */
2202 458 : bitalloc_var_fx = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /*Q14 */
2203 : }
2204 : ELSE
2205 : {
2206 7 : bitalloc_var_fx = 0; /*Q14 */
2207 7 : move16();
2208 : }
2209 : /* calculate the peak-average ratio of saturable subbands */
2210 465 : num = 0;
2211 465 : move16();
2212 465 : sharp_fx = 0;
2213 465 : move16();
2214 8117 : FOR( sfm = last_sfm; sfm >= 8; sfm-- )
2215 : {
2216 7652 : tmp = shl( sfmsize[sfm], 9 ); /*Q9 */
2217 7652 : tmp = mult( rat_fx[sfm], tmp ); /*Q(14+9-15=8) */
2218 7652 : IF( GE_16( shl_sat( R[sfm], 8 ), tmp ) )
2219 : {
2220 2407 : peak_fx = 0;
2221 2407 : move16();
2222 2407 : mean_fx = 0;
2223 2407 : move16();
2224 27703 : FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
2225 : {
2226 25296 : fabs_coeff_out_fx = L_abs( L_coeff_out[i] ); /*Q12*/
2227 25296 : mean_fx = L_add_sat( mean_fx, fabs_coeff_out_fx ); /*Q12 */
2228 25296 : if ( GT_32( fabs_coeff_out_fx, peak_fx ) )
2229 : {
2230 4470 : peak_fx = fabs_coeff_out_fx; /*Q12 */
2231 4470 : move32();
2232 : }
2233 : }
2234 :
2235 2407 : IF( mean_fx != 0 )
2236 : {
2237 2407 : exp = norm_l( mean_fx );
2238 2407 : mean_fx = L_shl_sat( mean_fx, exp ); /*Q(exp+12) */
2239 2407 : tmp = round_fx_sat( mean_fx ); /*Q(exp-4) */
2240 2407 : tmp = div_s( 16384, tmp ); /*Q(15+14-exp+4 = 33-exp) */
2241 2407 : L_tmp = Mult_32_16( peak_fx, tmp ); /*Q(12+33-exp-15 = 30-exp) */
2242 2407 : tmp = shl( sfmsize[sfm], 9 ); /*Q9 */
2243 2407 : L_tmp = Mult_32_16( L_tmp, tmp ); /*Q(30-exp+9-15 = 24-exp) */
2244 2407 : tmp = round_fx( L_shl( L_tmp, exp ) ); /*Q8 */
2245 2407 : sharp_fx = add( sharp_fx, tmp );
2246 : }
2247 2407 : num = add( num, 1 );
2248 : }
2249 : }
2250 465 : test();
2251 465 : IF( num != 0 && sharp_fx != 0 )
2252 : {
2253 448 : num = add( num, num );
2254 448 : exp = norm_s( sharp_fx );
2255 448 : sharp_fx = shl( sharp_fx, exp ); /*Q(8+exp) */
2256 448 : tmp = div_s( 16384, sharp_fx ); /*Q(21-exp) */
2257 448 : L_tmp = L_mult( num, tmp ); /*Q(22-exp) */
2258 448 : sharp_fx = round_fx( L_shl( L_tmp, add( 8, exp ) ) ); /*Q14 */
2259 : }
2260 : ELSE
2261 : {
2262 17 : sharp_fx = 16384; /*Q14 = 1 */
2263 17 : move16();
2264 : }
2265 465 : harm_para_fx = sharp_fx; /*Q14 */
2266 465 : move16();
2267 :
2268 465 : IF( last_sfm == 0 )
2269 : {
2270 0 : tmp = 0;
2271 0 : move16();
2272 : }
2273 : ELSE
2274 : {
2275 465 : tmp = div_s( 1, last_sfm ); /*Q15 */
2276 : }
2277 :
2278 465 : L_tmp = L_mult( 5, sharp_fx ); /*Q15 */
2279 465 : L_tmp = Mult_32_16( L_tmp, tmp ); /*Q15 */
2280 465 : step_fx = round_fx_sat( L_shl_sat( L_tmp, 16 ) ); /*Q15 */
2281 465 : alfa_fx = 20480; /*Q13 = 2.5 */
2282 465 : move16();
2283 : /* fill noise for the insaturable subbands */
2284 12555 : FOR( sfm = 0; sfm < num_sfm; sfm++ )
2285 : {
2286 12090 : env_fx = L_deposit_l( 0 );
2287 12090 : L_tmp2 = L_deposit_l( 0 );
2288 12090 : exp = 0;
2289 12090 : move16();
2290 12090 : test();
2291 12090 : IF( R[sfm] != 0 && LT_16( R[sfm], shl( mult( 24756, sfmsize[sfm] ), 1 ) ) )
2292 : {
2293 : /* calculate the energy of the undecoded coefficients */
2294 5497 : env_fx = L_deposit_l( 0 );
2295 5497 : exp1 = norm_l( L_normq_v[sfm] );
2296 5497 : L_tmp4 = L_shl( L_normq_v[sfm], exp1 ); /*14+exp1 */
2297 5497 : L_tmp1 = Mult_32_32( L_tmp4, L_tmp4 ); /*2*exp1-3 14+exp1+14+exp1 -31 */
2298 5497 : L_tmp2 = L_deposit_l( 0 );
2299 5497 : peak_fx = L_deposit_l( 0 );
2300 5497 : min_coef_fx = 0x7fffffff; /*Q31*/
2301 5497 : move32();
2302 :
2303 84305 : FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
2304 : {
2305 78808 : fabs_coeff_out_fx = L_abs( L_coeff_out[i] ); /*Q12*/
2306 78808 : test();
2307 78808 : if ( LT_32( fabs_coeff_out_fx, min_coef_fx ) && L_coeff_out[i] != 0 )
2308 : {
2309 7539 : min_coef_fx = fabs_coeff_out_fx; /*Q12*/
2310 7539 : move32();
2311 : }
2312 78808 : if ( GT_32( fabs_coeff_out_fx, peak_fx ) )
2313 : {
2314 7441 : peak_fx = fabs_coeff_out_fx; /*Q12*/
2315 7441 : move32();
2316 : }
2317 : }
2318 :
2319 5497 : exp2 = norm_l( peak_fx );
2320 84305 : FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
2321 : {
2322 78808 : L_tmp4 = L_shl( L_coeff_out[i], exp2 ); /*12+exp2 */
2323 78808 : L_tmp3 = L_shr( Mult_32_32( L_tmp4, L_tmp4 ), 4 ); /*2*exp2-7-4 12+exp2+12+exp2-31-4 */
2324 78808 : L_tmp2 = L_add( L_tmp2, L_tmp3 ); /*2*exp2-11 */
2325 : }
2326 :
2327 5497 : tmp1 = div_s( 1, sfmsize[sfm] ); /*15 */
2328 5497 : L_tmp4 = Mult_32_16( L_tmp2, tmp1 ); /*2*exp2-11 2*exp2-7+15+1-16 */
2329 :
2330 5497 : exp = norm_l( L_tmp1 );
2331 5497 : L_tmp1 = L_shl( L_tmp1, exp ); /*exp + 2*exp1 - 3 */
2332 5497 : exp1 = sub( add( exp, shl( exp1, 1 ) ), 3 );
2333 :
2334 5497 : exp = norm_l( L_tmp4 );
2335 5497 : L_tmp4 = L_shl( L_tmp4, exp ); /*exp + 2*exp1 - 3 */
2336 5497 : exp2 = sub( add( exp, shl( exp2, 1 ) ), 11 );
2337 5497 : exp = s_min( exp1, exp2 );
2338 :
2339 5497 : L_tmp1 = L_shl( L_tmp1, sub( exp, exp1 ) );
2340 5497 : L_tmp4 = L_shl( L_tmp4, sub( exp, exp2 ) );
2341 5497 : env_fx = L_sub( L_tmp1, L_tmp4 ); /*exp */
2342 5497 : exp1 = norm_l( env_fx );
2343 5497 : env_fx = L_shl( env_fx, exp1 ); /*exp + exp1 */
2344 5497 : exp = add( exp, exp1 );
2345 :
2346 5497 : IF( env_fx > 0 )
2347 : {
2348 5497 : IF( sfm == 0 )
2349 : {
2350 160 : avrg_norm_fx = L_add( L_shr( L_normq_v[0], 1 ), L_shr( L_normq_v[1], 1 ) ); /*13 */
2351 160 : avrg_norm_fx = L_add( avrg_norm_fx, L_shr( L_normq_v[2], 1 ) ); /*13 */
2352 160 : prev_avrg_norm_fx = L_add( L_shr( prev_normq_fx[0], 1 ), L_shr( prev_normq_fx[1], 1 ) ); /*13 */
2353 160 : prev_avrg_norm_fx = L_add( prev_avrg_norm_fx, L_shr( prev_normq_fx[2], 1 ) ); /*13 */
2354 : }
2355 5337 : ELSE IF( EQ_16( sfm, 25 ) )
2356 : {
2357 299 : avrg_norm_fx = L_add( L_shr( L_normq_v[23], 1 ), L_shr( L_normq_v[24], 1 ) ); /*13 */
2358 299 : avrg_norm_fx = L_add( avrg_norm_fx, L_shr( L_normq_v[25], 1 ) ); /*13 */
2359 299 : prev_avrg_norm_fx = L_add( L_shr( prev_normq_fx[23], 1 ), L_shr( prev_normq_fx[24], 1 ) ); /*13 */
2360 299 : prev_avrg_norm_fx = L_add( prev_avrg_norm_fx, L_shr( prev_normq_fx[25], 1 ) ); /*13 */
2361 : }
2362 : ELSE
2363 : {
2364 5038 : avrg_norm_fx = L_add( L_shr( L_normq_v[( sfm - 1 )], 1 ), L_shr( L_normq_v[sfm], 1 ) ); /*13 */
2365 5038 : avrg_norm_fx = L_add( avrg_norm_fx, L_shr( L_normq_v[sfm + 1], 1 ) ); /*13 */
2366 5038 : prev_avrg_norm_fx = L_add( L_shr( prev_normq_fx[( sfm - 1 )], 1 ), L_shr( prev_normq_fx[sfm], 1 ) ); /*13 */
2367 5038 : prev_avrg_norm_fx = L_add( prev_avrg_norm_fx, L_shr( prev_normq_fx[( sfm + 1 )], 1 ) ); /*13 */
2368 : }
2369 :
2370 5497 : test();
2371 5497 : test();
2372 5497 : IF( ( GT_16( bitalloc_var_fx, 4915 ) || LT_32( L_normq_v[sfm], peak_fx ) ) && peak_fx != 0 )
2373 5401 : {
2374 : Word16 exp_p;
2375 5401 : exp_p = norm_l( peak_fx );
2376 5401 : exp = sub( 31, exp );
2377 5401 : env_fx = Isqrt_lc( env_fx, &exp ); /*Q31 - exp*/
2378 5401 : L_tmp1 = Mult_32_32( env_fx, L_shl( peak_fx, exp_p ) ); /*12+exp2-exp 31-exp+12+exp1-31 */
2379 5401 : L_tmp2 = Mult_32_16( avrg_norm_fx, harm_para_fx ); /*12 13 + 14 + 1 -16 */
2380 5401 : exp1 = norm_l( L_tmp1 );
2381 5401 : L_tmp1 = L_shl( L_tmp1, exp1 ); /* 12+exp2-exp+exp1 */
2382 5401 : exp = add( sub( 12, exp ), add( exp1, exp_p ) );
2383 5401 : L_tmp2 = Div_32( L_tmp2, extract_h( L_tmp1 ), extract_l( L_tmp1 ) ); /*Q31 - (43-exp)*/
2384 5401 : exp = sub( 43, exp );
2385 : }
2386 : ELSE
2387 : {
2388 96 : L_tmp1 = Mult_32_16( L_normq_v[sfm], alfa_fx ); /*12 13 + 14 + 1 -16 */
2389 96 : IF( LT_32( L_tmp1, peak_fx ) )
2390 : {
2391 1 : exp = sub( 31, exp );
2392 1 : env_fx = Isqrt_lc( env_fx, &exp ); /*Q31 - exp*/
2393 1 : exp1 = norm_l( env_fx );
2394 1 : env_fx = L_shl( env_fx, exp1 ); /* 31-exp+exp1 */
2395 1 : exp = add( sub( 31, exp ), exp1 );
2396 1 : L_tmp1 = L_deposit_l( sharp_fx ); /*Q14*/
2397 1 : L_tmp2 = Div_32( L_tmp1, extract_h( env_fx ), extract_l( env_fx ) ); /* 45-exp 14 - exp + 31 //39-exp 8 - exp + 31 */
2398 1 : exp = sub( 45, exp );
2399 1 : exp1 = norm_l( peak_fx );
2400 1 : L_tmp1 = L_shl( peak_fx, exp1 ); /*12 + exp1 */
2401 1 : L_tmp1 = Div_32( L_tmp2, extract_h( L_tmp1 ), extract_l( L_tmp1 ) ); /* exp - (12 + exp1) +31 */
2402 1 : L_tmp2 = Mult_32_32( L_tmp2, L_tmp1 ); /*2*exp+exp1-12 exp +exp - (12 + exp1) +31 - 31 */
2403 1 : exp = sub( add( shl( exp, 1 ), exp1 ), 12 );
2404 : }
2405 : ELSE
2406 : {
2407 95 : exp = sub( 31, exp );
2408 95 : env_fx = Isqrt_lc( env_fx, &exp ); /*Q31 - exp*/
2409 95 : exp1 = norm_l( env_fx );
2410 95 : env_fx = L_shl( env_fx, exp1 ); /* 31-exp+exp1 */
2411 95 : exp = add( sub( 31, exp ), exp1 );
2412 95 : L_tmp1 = L_deposit_l( sharp_fx ); /*Q14*/
2413 95 : L_tmp2 = Div_32( L_tmp1, extract_h( env_fx ), extract_l( env_fx ) ); /* 45-exp 14 - exp + 31 //39-exp 8 - exp + 31 */
2414 95 : exp = sub( 45, exp );
2415 : }
2416 :
2417 96 : sharp_fx = add_sat( sharp_fx, shr( step_fx, 1 ) ); /*Q14*/
2418 : }
2419 :
2420 5497 : IF( GT_32( L_tmp2, L_shl_sat( min_coef_fx, sub( exp, 13 ) ) ) ) /*exp */
2421 : {
2422 2380 : L_tmp2 = L_shr( min_coef_fx, 1 );
2423 2380 : exp = 12;
2424 2380 : move16();
2425 : }
2426 :
2427 5497 : IF( EQ_16( prev_bfi, 1 ) )
2428 : {
2429 45 : prev_env_Q[sfm] = exp;
2430 45 : move16();
2431 45 : prev_env_fx[sfm] = L_tmp2;
2432 45 : move32();
2433 : }
2434 : /* smooth the noise magnitudes between inter-frame */
2435 5497 : test();
2436 5497 : test();
2437 5497 : IF( GT_32( prev_avrg_norm_fx, L_shr( avrg_norm_fx, 1 ) ) && LT_32( prev_avrg_norm_fx, L_shl_sat( avrg_norm_fx, 1 ) ) && prev_is_transient == 0 )
2438 : {
2439 3100 : exp1 = norm_l( prev_env_fx[sfm] );
2440 3100 : L_tmp1 = L_shl( prev_env_fx[sfm], exp1 ); /* prev_env_Q[sfm] +exp1 */
2441 :
2442 3100 : exp2 = norm_l( L_tmp2 );
2443 3100 : L_tmp3 = L_shl( L_tmp2, exp2 ); /* exp +exp2 */
2444 3100 : exp3 = s_min( add( prev_env_Q[sfm], exp1 ), add( exp, exp2 ) );
2445 :
2446 3100 : L_tmp1 = L_shl( L_tmp1, sub( sub( exp3, prev_env_Q[sfm] ), exp1 ) ); /*exp3 */
2447 3100 : L_tmp3 = L_shl( L_tmp3, sub( sub( exp3, exp ), exp2 ) ); /*exp3 */
2448 3100 : L_tmp2 = L_add( L_shr( L_tmp1, 1 ), L_shr( L_tmp3, 1 ) ); /*exp3 */
2449 3100 : exp = exp3;
2450 3100 : move16();
2451 : }
2452 84305 : FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
2453 : {
2454 78808 : IF( coeff_fx[i] == 0 )
2455 : {
2456 65593 : tmp1 = Random( bwe_seed ); /*Q15 */
2457 65593 : L_tmp1 = Mult_32_16( L_tmp2, tmp1 ); /*exp exp+15+1 -16 */
2458 65593 : L_tmp1 = L_shl( L_tmp1, sub( 12, exp ) ); /*Q12*/
2459 65593 : L_coeff_out[i] = L_tmp1; /*Q12*/
2460 65593 : move32();
2461 : }
2462 : }
2463 : }
2464 : ELSE
2465 : {
2466 0 : exp = 0;
2467 0 : move16();
2468 0 : L_tmp2 = L_deposit_l( 0 );
2469 : }
2470 : }
2471 6593 : ELSE IF( R[sfm] == 0 )
2472 : {
2473 : /* fill random noise for 0 bit subbands */
2474 36188 : FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
2475 : {
2476 34008 : IF( coeff_fx[i] == 0 )
2477 : {
2478 16919 : tmp1 = Random( bwe_seed ); /*Q15 */
2479 16919 : L_tmp1 = Mult_32_16( L_normq_v[sfm], tmp1 ); /*14 14+15+1 -16 */
2480 16919 : L_tmp1 = L_shr( L_tmp1, 2 ); /*Q12 */
2481 16919 : L_coeff_out[i] = L_tmp1; /*Q12*/
2482 16919 : move32();
2483 : }
2484 : }
2485 2180 : L_tmp2 = L_normq_v[sfm]; /*Q14*/
2486 2180 : move32();
2487 2180 : exp = 14;
2488 2180 : move16();
2489 : }
2490 :
2491 12090 : test();
2492 12090 : test();
2493 12090 : test();
2494 12090 : test();
2495 12090 : IF( EQ_16( sfm, sub( SFM_N_WB, 1 ) ) && prev_is_transient == 0 && GT_32( prev_normq_fx[sfm], L_shr( L_normq_v[sfm], 1 ) ) && LT_32( prev_normq_fx[sfm], L_shl_sat( L_normq_v[sfm], 1 ) ) && LE_16( bitalloc_var_fx, 4915 ) )
2496 : {
2497 0 : Word32 *p_prev_coeff_out = prev_coeff_out_fx; /*Q12*/
2498 0 : FOR( i = add( sfm_start[sfm], 12 ); i < sfm_end[sfm]; i++ )
2499 : {
2500 0 : test();
2501 0 : test();
2502 0 : test();
2503 0 : test();
2504 0 : IF( GT_32( L_abs( L_coeff_out[i] ), L_shl_sat( L_abs( *p_prev_coeff_out ), 2 ) ) || LT_32( L_abs( L_coeff_out[i] ), L_shr( L_abs( *p_prev_coeff_out ), 2 ) ) || ( ( R[sfm] == 0 || *prev_R == 0 ) && add_sat( R[sfm], *prev_R ) != 0 ) )
2505 : {
2506 0 : L_tmp = L_add_sat( L_shr( L_abs( L_coeff_out[i] ), 1 ), L_shr( L_abs( *p_prev_coeff_out ), 1 ) ); /*Q12*/
2507 0 : if ( L_coeff_out[i] <= 0 )
2508 : {
2509 0 : L_tmp = L_negate( L_tmp ); /*Q12*/
2510 : }
2511 0 : L_coeff_out[i] = L_tmp; /*Q12*/
2512 0 : move32();
2513 : }
2514 0 : p_prev_coeff_out++; /*Q12*/
2515 : }
2516 : }
2517 12090 : prev_env_Q[sfm] = exp;
2518 12090 : move16();
2519 12090 : prev_env_fx[sfm] = L_tmp2;
2520 12090 : move32();
2521 : }
2522 : }
2523 : ELSE
2524 : {
2525 : /* fill random noise for 0 bit subbands of transient frame */
2526 297 : FOR( sfm = 0; sfm < num_sfm; sfm++ )
2527 : {
2528 286 : IF( R[sfm] == 0 )
2529 : {
2530 1507 : FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
2531 : {
2532 1392 : tmp1 = Random( bwe_seed ); /*Q15 */
2533 1392 : L_tmp1 = Mult_32_16( L_normq_v[sfm], tmp1 ); /*14 14+15+1 -16 */
2534 1392 : L_tmp1 = L_shr( L_tmp1, 2 ); /*Q12*/
2535 1392 : L_coeff_out[i] = L_tmp1; /*Q12*/
2536 1392 : move32();
2537 : }
2538 : }
2539 : }
2540 11 : set16_fx( prev_env_Q, 0, SFM_N_WB );
2541 11 : set32_fx( prev_env_fx, 0, SFM_N_WB );
2542 : }
2543 :
2544 476 : Copy32( L_normq_v, prev_normq_fx, SFM_N_WB ); /*Q14*/
2545 476 : Copy32( L_coeff_out + L_FRAME16k - L_HQ_WB_BWE, prev_coeff_out_fx, L_HQ_WB_BWE ); /*Q12*/
2546 476 : *prev_R = R[SFM_N_WB - 1]; /*Q0*/
2547 476 : move16();
2548 :
2549 476 : return;
2550 : }
2551 :
2552 : /*--------------------------------------------------------------------------*
2553 : * enforce_zero_for_min_envelope_fx()
2554 : *
2555 : * Detect minimum level of envelope and set corresponding bands to zero
2556 : *--------------------------------------------------------------------------*/
2557 :
2558 7728 : void enforce_zero_for_min_envelope_fx(
2559 : const Word16 hqswb_clas, /* i : HQ coding mode Q0 */
2560 : const Word16 *ynrm, /* i : Envelope indices Q0 */
2561 : Word32 *L_coefsq, /* i/o: Quantized spectrum/zeroed spectrum Q12 */
2562 : const Word16 nb_sfm, /* i : Number of coded sub bands Q0 */
2563 : const Word16 *sfm_start, /* i : Sub band start indices Q0 */
2564 : const Word16 *sfm_end /* i : Sub band end indices Q0 */
2565 : )
2566 : {
2567 : Word16 i, j;
2568 :
2569 : /* prevent non-zero output for all-zero input */
2570 7728 : IF( NE_16( hqswb_clas, HQ_HVQ ) )
2571 : {
2572 6499 : IF( EQ_16( ynrm[0], 31 ) )
2573 : {
2574 36 : FOR( j = sfm_start[0]; j < sfm_end[0]; j++ )
2575 : {
2576 32 : L_coefsq[j] = L_deposit_l( 0 ); /*Q12*/
2577 32 : move32();
2578 : }
2579 : }
2580 :
2581 260385 : FOR( i = 1; i < nb_sfm; i++ )
2582 : {
2583 253886 : IF( EQ_16( ynrm[i], 39 ) )
2584 : {
2585 162935 : FOR( j = sfm_start[i]; j < sfm_end[i]; j++ )
2586 : {
2587 157320 : L_coefsq[j] = L_deposit_l( 0 ); /*Q12*/
2588 157320 : move32();
2589 : }
2590 : }
2591 : }
2592 : }
2593 :
2594 7728 : return;
2595 : }
2596 : /*--------------------------------------------------------------------------*
2597 : * apply_envelope()
2598 : *
2599 : * Apply spectral envelope with envelope adjustments
2600 : *--------------------------------------------------------------------------*/
2601 :
2602 6352 : void apply_envelope_enc_ivas_fx(
2603 : const Word16 *coeff, /* i/o: Coded/noisefilled normalized spectrum Q12 */
2604 : const Word16 *norm, /* i : Envelope Q0 */
2605 : const Word16 num_sfm, /* i : Total number of bands Q0 */
2606 : const Word16 *sfm_start, /* i : Sub band start indices Q0 */
2607 : const Word16 *sfm_end, /* i : Sub band end indices Q0 */
2608 : Word32 *coeff_out /* o : coded/noisefilled spectrum Q12 */
2609 : )
2610 : {
2611 : Word16 i;
2612 : Word16 sfm;
2613 : UWord16 lsb;
2614 : Word32 normq;
2615 : Word32 L_tmp;
2616 :
2617 263750 : FOR( sfm = 0; sfm < num_sfm; sfm++ )
2618 : {
2619 257398 : normq = dicn_fx[norm[sfm]]; /*Q14*/
2620 257398 : move16();
2621 :
2622 4978838 : FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
2623 : {
2624 : /*coeff_out[i] = coeff[i]*normq; */
2625 4721440 : Mpy_32_16_ss( normq, coeff[i], &L_tmp, &lsb );
2626 4721440 : coeff_out[i] = L_add( L_shl( L_tmp, 1 ), L_shr( lsb, 15 ) ); /*Q12*/
2627 4721440 : move32();
2628 : }
2629 : }
2630 :
2631 :
2632 6352 : return;
2633 : }
2634 :
2635 : /*--------------------------------------------------------------------------*
2636 : * apply_envelope()
2637 : *
2638 : * Apply spectral envelope with envelope adjustments
2639 : *--------------------------------------------------------------------------*/
2640 :
2641 5771 : void apply_envelope_fx(
2642 : const Word16 *coeff, /* i/o: Coded/noisefilled normalized spectrum Q12 */
2643 : const Word16 *norm, /* i : Envelope Q0 */
2644 : const Word16 *norm_adj, /* i : Envelope adjustment Q15 */
2645 : const Word16 num_sfm, /* i : Total number of bands Q0 */
2646 : const Word16 last_sfm, /* i : Last coded band Q0 */
2647 : const Word16 HQ_mode, /* i : HQ mode Q0 */
2648 : const Word16 length, /* i : Frame length Q0 */
2649 : const Word16 *sfm_start, /* i : Sub band start indices Q0 */
2650 : const Word16 *sfm_end, /* i : Sub band end indices Q0 */
2651 : Word32 *normq_v, /* o : Envelope with adjustment Q14 */
2652 : Word32 *coeff_out, /* o : coded/noisefilled spectrum Q12 */
2653 : const Word16 *coeff1, /* i : coded/noisefilled spectrum Q12 */
2654 : Word32 *coeff_out1 /* o : coded/noisefilled spectrum Q12 */
2655 : )
2656 : {
2657 : Word16 i;
2658 : Word16 sfm;
2659 : UWord16 lsb;
2660 : Word32 normq;
2661 : Word32 L_tmp;
2662 : Word16 len;
2663 :
2664 5771 : len = num_sfm;
2665 5771 : move16();
2666 5771 : test();
2667 5771 : if ( EQ_16( HQ_mode, HQ_GEN_SWB ) || EQ_16( HQ_mode, HQ_GEN_FB ) )
2668 : {
2669 2789 : len = add( last_sfm, 1 ); /*Q0*/
2670 : }
2671 :
2672 5771 : IF( EQ_16( length, L_FRAME16k ) )
2673 : {
2674 16092 : FOR( sfm = 0; sfm < num_sfm; sfm++ )
2675 : {
2676 15496 : normq_v[sfm] = dicn_fx[norm[sfm]]; /*Q14*/
2677 15496 : move16();
2678 15496 : move32();
2679 : /*normq = normq_v[sfm] * norm_adj[sfm]; */
2680 15496 : Mpy_32_16_ss( normq_v[sfm], norm_adj[sfm], &normq, &lsb ); /* Q14 (14+15+1-16) */
2681 :
2682 206216 : FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
2683 : {
2684 : /*coeff_out[i] = coeff[i]*normq; */
2685 190720 : Mpy_32_16_ss( normq, coeff[i], &L_tmp, &lsb );
2686 190720 : coeff_out[i] = L_add( L_shl( L_tmp, 1 ), L_shr( lsb, 15 ) ); /* Q12 (14+12+1-16)+1 */
2687 190720 : move32();
2688 : }
2689 : }
2690 : }
2691 : ELSE
2692 : {
2693 182419 : FOR( sfm = 0; sfm < len; sfm++ )
2694 : {
2695 177244 : normq_v[sfm] = dicn_fx[norm[sfm]]; /*Q14*/
2696 177244 : move16();
2697 177244 : move32();
2698 : /*normq_v[sfm] *= norm_adj[sfm]; */
2699 177244 : Mpy_32_16_ss( normq_v[sfm], norm_adj[sfm], &normq_v[sfm], &lsb ); /* Q14 (14+15+1-16) */
2700 177244 : move32();
2701 :
2702 177244 : normq = normq_v[sfm]; /*Q14*/
2703 177244 : move32();
2704 2926980 : FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
2705 : {
2706 : /*coeff_out[i] = coeff[i]*normq; */
2707 2749736 : Mpy_32_16_ss( normq, coeff[i], &L_tmp, &lsb );
2708 2749736 : coeff_out[i] = L_add( L_shl( L_tmp, 1 ), L_shr( lsb, 15 ) ); /* Q12 (14+12+1-16)+1 */
2709 2749736 : move32();
2710 : }
2711 : }
2712 :
2713 5175 : test();
2714 5175 : IF( EQ_16( HQ_mode, HQ_GEN_SWB ) || EQ_16( HQ_mode, HQ_GEN_FB ) )
2715 : {
2716 78103 : FOR( sfm = 0; sfm <= last_sfm; sfm++ )
2717 : {
2718 75314 : normq = normq_v[sfm];
2719 75314 : move32();
2720 990370 : FOR( i = sfm_start[sfm]; i < sfm_end[sfm]; i++ )
2721 : {
2722 : /*coeff_out1[i] = coeff_out1[i]*normq; */
2723 915056 : Mpy_32_16_ss( normq, coeff1[i], &L_tmp, &lsb );
2724 915056 : coeff_out1[i] = L_add( L_shl( L_tmp, 1 ), L_shr( lsb, 15 ) ); /* Q12 (14+12+1-16)+1 */
2725 915056 : move32();
2726 : }
2727 : }
2728 : }
2729 : }
2730 :
2731 :
2732 5771 : return;
2733 : }
|