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 : #include <stdint.h>
34 : #include "options.h"
35 : #include "cnst.h"
36 : #include "prot_fx.h"
37 : #include "rom_com.h"
38 :
39 : #include <assert.h>
40 :
41 : /*-------------------------------------------------------------------*
42 : * GetPredictedSignal()
43 : *
44 : * Routine for calculating the predicted signal
45 : *-------------------------------------------------------------------*/
46 264 : void GetPredictedSignal_fx(
47 : const Word16 *predBuf_fx, /* i: Q8 */
48 : Word32 *L_outBuf, /* o: Q9 */
49 : const Word16 lag_fx, /* i: Q0 */
50 : const Word16 fLen_fx, /* i: Q0 */
51 : const Word16 lagGains_fx, /* i: Qgain */
52 : const Word16 Qgain /* i: Q0 */
53 : )
54 : {
55 : Word16 i;
56 : const Word16 *p_predBuf;
57 : Word32 *p_L_outBuf;
58 :
59 264 : p_predBuf = predBuf_fx + lag_fx;
60 264 : p_L_outBuf = L_outBuf;
61 :
62 20856 : FOR( i = 0; i < fLen_fx; i++ )
63 : {
64 : /* Q8 x Q0 --> Q9, 9+7-16=Q0 */
65 20592 : *p_L_outBuf++ = L_shr( L_mult( *p_predBuf++, lagGains_fx ), Qgain );
66 20592 : move32();
67 : }
68 264 : }
69 :
70 : /*-------------------------------------------------------------------*
71 : * est_freq_har_decis_fx()
72 : *
73 : * Harmonic frequency decision matrix
74 : *-------------------------------------------------------------------*/
75 4221 : static void est_freq_har_decis_fx(
76 : Word16 *har_freq_est1, /* o: harmonic analysis 1 */
77 : Word16 *har_freq_est2, /* o: harmonic analysis 2 */
78 : Word16 sharp, /* i: pka-avg for group 1 */
79 : Word16 sharp1, /* i: pka-avg for group 2 */
80 : Word16 hfe_est_countk1, /* i: group pks count 1 */
81 : Word16 hfe_est_countk2, /* i: group pks count 2 */
82 : Word16 k, /* i: group count */
83 : Word16 k1, /* i: */
84 : Word16 k2, /* i: */
85 : Word16 *prev_frm_hfe2 /* i: harmonic estimation */
86 : )
87 : {
88 4221 : Word16 temp_hfe2 = 0;
89 4221 : move16();
90 : Word16 har_freq_est2_2;
91 : Word16 prev_frm_hfe2_2;
92 :
93 4221 : IF( k != 0 )
94 : {
95 4221 : *har_freq_est1 = div_s_ss( sharp, k );
96 4221 : move16();
97 : }
98 :
99 4221 : test();
100 4221 : test();
101 4221 : IF( GT_16( k1, 1 ) )
102 : {
103 1698 : *har_freq_est2 = div_s_ss( sharp1, k1 );
104 1698 : move16();
105 : }
106 2523 : ELSE IF( LT_16( k1, 2 ) && ( k2 != 0 || GT_16( k, 1 ) ) )
107 : {
108 2461 : *har_freq_est2 = *har_freq_est1;
109 2461 : move16();
110 : }
111 : ELSE
112 : {
113 62 : test();
114 62 : test();
115 62 : test();
116 62 : IF( ( hfe_est_countk1 != 0 || hfe_est_countk2 != 0 ) && ( k1 == 0 && k2 == 0 ) )
117 : {
118 54 : *har_freq_est2 = ( *har_freq_est1 );
119 54 : move16();
120 : }
121 : ELSE
122 : {
123 8 : *har_freq_est2 = shl( *har_freq_est1, 1 );
124 8 : move16();
125 : }
126 : }
127 :
128 : /* Consider Estimation Error upto 200Hz */
129 4221 : test();
130 4221 : test();
131 4221 : test();
132 4221 : har_freq_est2_2 = shl( *har_freq_est2, 1 );
133 4221 : prev_frm_hfe2_2 = shl( *prev_frm_hfe2, 1 );
134 4221 : IF( *prev_frm_hfe2 != 0 && ( LT_16( abs_s( sub( *prev_frm_hfe2, *har_freq_est2 ) ), 10 ) || LT_16( abs_s( sub( *prev_frm_hfe2, har_freq_est2_2 ) ), 10 ) ) )
135 : {
136 0 : *har_freq_est2 = *prev_frm_hfe2;
137 0 : move16();
138 : }
139 4221 : ELSE IF( *prev_frm_hfe2 != 0 && LT_16( abs_s( sub( *har_freq_est2, prev_frm_hfe2_2 ) ), 10 ) )
140 : {
141 0 : *har_freq_est2 = prev_frm_hfe2_2;
142 0 : move16();
143 : }
144 : ELSE
145 : {
146 4221 : temp_hfe2 = shr( add( *prev_frm_hfe2, *har_freq_est2 ), 1 );
147 4221 : move16();
148 :
149 4221 : IF( LT_16( abs_s( sub( temp_hfe2, *prev_frm_hfe2 ) ), 2 ) )
150 : {
151 0 : temp_hfe2 = *prev_frm_hfe2;
152 0 : move16();
153 0 : *har_freq_est2 = temp_hfe2;
154 0 : move16();
155 : }
156 : }
157 :
158 4221 : test();
159 4221 : test();
160 4221 : if ( LT_16( *har_freq_est2, *har_freq_est1 ) && ( GT_16( k, 1 ) && LT_16( k1, 2 ) ) )
161 : {
162 0 : *har_freq_est2 = *har_freq_est1;
163 0 : move16();
164 : }
165 :
166 4221 : return;
167 : }
168 :
169 : /*--------------------------------------------------------------------------*
170 : * har_est_fx()
171 : *
172 : * Harmonic Structure analysis using LF spectrum
173 : *--------------------------------------------------------------------------*/
174 :
175 4221 : Word16 har_est_fx(
176 : Word32 L_spectra[], /* i : coded spectrum */
177 : Word16 N, /* i : length of the desired spectrum */
178 : Word16 *har_freq_est1, /* i/o: Estimation harmonics 1 */
179 : Word16 *har_freq_est2, /* o : Estimation harmonics 2 */
180 : Word16 *flag_dis, /* i/o: flag for BWE reconstruction */
181 : Word16 *prev_frm_hfe2, /* i/o: Estimated harmonic update */
182 : const Word16 subband_search_offset[], /* i : Subband Search range */
183 : const Word16 sbWidth[], /* i : Subband Search range */
184 : Word16 *prev_stab_hfe2 /* i/o: Estimated harmonic position */
185 : )
186 : {
187 : Word32 L_peak;
188 : Word32 L_input_abs[L_FRAME32k], L_blk_peak[30];
189 : Word32 L_blk_peak_te[30];
190 : Word32 L_blk_peak_max;
191 : Word32 *p_L_blk_peak, *pm1_L_blk_peak;
192 :
193 : Word16 i, j, q, k, k1, k2;
194 : Word16 blk_end, blk_st;
195 : Word16 peak_pos, blk_peak_pos[30], diff_peak_pos[30], sharp, sharp1;
196 : Word16 min_har_pos;
197 : Word16 blk_peak_pos_te[30];
198 : Word16 temp;
199 : Word16 hfe_est_countk, hfe_est_countk1, hfe_est_countk2;
200 : Word16 r1, r2, r3;
201 : Word16 start_pos;
202 : Word16 blk_peak_pos_max;
203 :
204 : Word16 nlags, nlags_half, ct_hfsb2, sum_diff;
205 : Word16 blk_peak_pos_hfsb2[30], diff_peak_pos_hfsb2[30];
206 : Word16 rem_hfe2, q_diffpos_hfe2, diff_posmax_hfe2, q_diffpos_prevhfe2;
207 :
208 : Word16 blk_end_LEN;
209 :
210 : Word16 *p_blk_peak_pos, *pm1_blk_peak_pos;
211 : Word16 *pm1_diff_peak_pos;
212 : Word16 blk_peak_max_idx, blk_peak_pos_max_diff, diff_peak_pos_te[30];
213 : Word16 thr1, thr2;
214 :
215 4221 : set32_fx( L_input_abs, 0x0L, L_FRAME32k );
216 4221 : set32_fx( L_blk_peak, 0x0L, 30 );
217 4221 : set16_fx( blk_peak_pos, 0, 30 );
218 4221 : set16_fx( blk_peak_pos_te, 0, 30 );
219 :
220 4221 : rem_hfe2 = 0;
221 4221 : move16();
222 4221 : q_diffpos_hfe2 = 0;
223 4221 : move16();
224 4221 : diff_posmax_hfe2 = 0;
225 4221 : move16();
226 4221 : q_diffpos_prevhfe2 = 0;
227 4221 : move16();
228 :
229 4221 : set16_fx( diff_peak_pos, 0, 30 );
230 :
231 4221 : r1 = SWB_HAR_RAN1;
232 4221 : move16();
233 4221 : r2 = SWB_HAR_RAN2;
234 4221 : move16();
235 4221 : r3 = SWB_HAR_RAN3;
236 4221 : move16();
237 4221 : start_pos = r1;
238 4221 : move16();
239 :
240 : /* Copy the abs values of LF spectrum*/
241 932841 : FOR( i = start_pos; i < N; i++ )
242 : {
243 928620 : L_input_abs[i] = L_abs( L_spectra[i] );
244 928620 : move32();
245 : }
246 :
247 4221 : blk_end = div_s_ss( N, LR_BLK_LEN );
248 4221 : blk_st = div_s_ss( start_pos, LR_BLK_LEN );
249 :
250 : /*if( N/(LR_BLK_LEN) - blk_end > 0.0f) */
251 4221 : blk_end_LEN = i_mult( blk_end, LR_BLK_LEN );
252 4221 : if ( GT_16( N, blk_end_LEN ) )
253 : {
254 4221 : blk_end = add( blk_end, 1 );
255 : }
256 :
257 : /* initialization of over buffer for fractional point */
258 4221 : temp = i_mult( blk_end, LR_BLK_LEN );
259 21105 : FOR( i = N; i < temp; i++ )
260 : {
261 16884 : L_input_abs[i] = L_deposit_l( 0 );
262 16884 : move16();
263 : }
264 :
265 4221 : q = start_pos;
266 4221 : move16();
267 :
268 : /* Block Processing, to detect the spectral peaks*/
269 63315 : FOR( i = blk_st; i < blk_end; i++ )
270 : {
271 59094 : L_peak = L_deposit_l( 0 );
272 59094 : peak_pos = 0;
273 59094 : move16();
274 :
275 1004598 : FOR( j = 0; j < LR_BLK_LEN; j++ )
276 : {
277 945504 : IF( GT_32( L_input_abs[q], L_peak ) )
278 : {
279 149394 : L_peak = L_input_abs[q];
280 149394 : move32();
281 149394 : peak_pos = q;
282 149394 : move16();
283 : }
284 :
285 945504 : test();
286 945504 : test();
287 945504 : test();
288 945504 : IF( GT_16( i, blk_st ) && L_input_abs[q] != 0x0L && EQ_32( L_input_abs[q], L_peak ) && LT_16( sub( peak_pos, blk_peak_pos[i - 1] ), LR_HLF_PK_BLK_LEN ) )
289 : {
290 28679 : L_peak = L_input_abs[q];
291 28679 : move32();
292 28679 : peak_pos = q;
293 28679 : move16();
294 : }
295 945504 : q = add( q, 1 );
296 : }
297 :
298 59094 : L_blk_peak[i] = L_peak;
299 59094 : move32();
300 59094 : blk_peak_pos[i] = peak_pos;
301 59094 : move16();
302 : }
303 :
304 4221 : p_L_blk_peak = &L_blk_peak[blk_st];
305 4221 : pm1_L_blk_peak = &L_blk_peak[sub( blk_st, 1 )];
306 4221 : p_blk_peak_pos = &blk_peak_pos[blk_st];
307 4221 : pm1_blk_peak_pos = &blk_peak_pos[sub( blk_st, 1 )];
308 63315 : FOR( i = blk_st; i < blk_end; i++ )
309 : {
310 59094 : IF( GT_16( i, blk_st ) )
311 : {
312 :
313 54873 : test();
314 54873 : IF( *p_blk_peak_pos != 0 && *pm1_blk_peak_pos != 0 )
315 : {
316 40417 : IF( LT_16( sub( *p_blk_peak_pos, *pm1_blk_peak_pos ), LR_LOWBAND_DIF_PK_LEN ) )
317 : {
318 6700 : IF( GT_32( *p_L_blk_peak, *pm1_L_blk_peak ) )
319 : {
320 4341 : *pm1_L_blk_peak = L_deposit_l( 0 );
321 4341 : move32();
322 4341 : *pm1_blk_peak_pos = 0;
323 4341 : move16();
324 : }
325 : ELSE
326 : {
327 2359 : *p_L_blk_peak = *pm1_L_blk_peak;
328 2359 : move32();
329 2359 : *p_blk_peak_pos = *pm1_blk_peak_pos;
330 2359 : move16();
331 2359 : *pm1_L_blk_peak = L_deposit_l( 0 );
332 2359 : move32();
333 2359 : *pm1_blk_peak_pos = 0;
334 2359 : move16();
335 : }
336 : }
337 : }
338 : }
339 59094 : p_L_blk_peak++;
340 59094 : pm1_L_blk_peak++;
341 :
342 59094 : p_blk_peak_pos++;
343 59094 : pm1_blk_peak_pos++;
344 : }
345 :
346 : /* peak counts in each group */
347 4221 : j = 0;
348 4221 : move16();
349 4221 : hfe_est_countk = 0;
350 4221 : move16();
351 4221 : hfe_est_countk1 = 0;
352 4221 : move16();
353 4221 : hfe_est_countk2 = 0;
354 4221 : move16();
355 63315 : FOR( i = blk_st; i < blk_end; i++ )
356 : {
357 59094 : IF( blk_peak_pos[i] != 0 )
358 : {
359 39679 : blk_peak_pos_te[j] = blk_peak_pos[i];
360 39679 : move16();
361 39679 : IF( LT_16( blk_peak_pos[i], r2 ) )
362 : {
363 13293 : hfe_est_countk = add( hfe_est_countk, 1 );
364 : }
365 26386 : ELSE IF( LT_16( blk_peak_pos[i], r3 ) )
366 : {
367 12157 : hfe_est_countk1 = add( hfe_est_countk1, 1 );
368 : }
369 : ELSE
370 : {
371 14229 : hfe_est_countk2 = add( hfe_est_countk2, 1 );
372 : }
373 39679 : L_blk_peak_te[j] = L_blk_peak[i];
374 39679 : move32();
375 39679 : j = add( j, 1 );
376 : }
377 : }
378 :
379 4221 : min_har_pos = SWB_HAR_RAN1;
380 4221 : move16();
381 4221 : temp = 0;
382 4221 : move16();
383 4221 : L_blk_peak_max = L_blk_peak_te[0];
384 4221 : move32();
385 4221 : blk_peak_pos_max = blk_peak_pos_te[0];
386 4221 : move16();
387 4221 : blk_peak_max_idx = 0;
388 4221 : move16();
389 :
390 4221 : pm1_diff_peak_pos = &diff_peak_pos[1 - 1];
391 39679 : FOR( i = 1; i < j; i++ )
392 : {
393 35458 : *pm1_diff_peak_pos = sub( blk_peak_pos_te[i], blk_peak_pos_te[sub( i, 1 )] );
394 35458 : if ( LE_16( *pm1_diff_peak_pos, min_har_pos ) )
395 : {
396 12912 : min_har_pos = *pm1_diff_peak_pos;
397 12912 : move16();
398 : }
399 :
400 35458 : IF( GT_32( L_blk_peak_te[sub( i, 1 )], L_blk_peak_max ) )
401 : {
402 6833 : L_blk_peak_max = L_blk_peak_te[sub( i, 1 )];
403 6833 : move32();
404 6833 : blk_peak_pos_max = blk_peak_pos_te[sub( i, 1 )];
405 6833 : move16();
406 6833 : blk_peak_max_idx = sub( i, 1 );
407 : }
408 :
409 35458 : temp = add( temp, 1 );
410 :
411 35458 : pm1_diff_peak_pos++;
412 : }
413 4221 : blk_peak_pos_max_diff = diff_peak_pos[blk_peak_max_idx];
414 4221 : move16();
415 :
416 : /* Decision for BWE reconstruction */
417 4221 : test();
418 4221 : test();
419 4221 : test();
420 4221 : IF( ( LT_16( hfe_est_countk, 2 ) && LT_16( hfe_est_countk1, 2 ) && LT_16( hfe_est_countk2, 2 ) ) || GE_16( min_har_pos, SWB_HAR_RAN1 ) )
421 : {
422 0 : *flag_dis = 0;
423 0 : move16();
424 0 : test();
425 0 : test();
426 0 : test();
427 0 : if ( ( EQ_16( hfe_est_countk, 1 ) && EQ_16( hfe_est_countk1, 1 ) ) && ( EQ_16( hfe_est_countk2, 1 ) || hfe_est_countk2 == 0 ) )
428 : {
429 0 : *flag_dis = 1;
430 0 : move16();
431 : }
432 : }
433 4221 : thr1 = add( blk_peak_pos_max_diff, LR_LOWBAND_DIF_PK_LEN );
434 39679 : FOR( i = 0; i < temp; i++ )
435 : {
436 35458 : if ( LT_16( thr1, diff_peak_pos[i] ) )
437 : {
438 3547 : diff_peak_pos[i] = 0;
439 3547 : move16();
440 : }
441 : }
442 4221 : Copy( diff_peak_pos, diff_peak_pos_te, temp );
443 4221 : set16_fx( diff_peak_pos, -1, temp );
444 4221 : j = 0;
445 39679 : FOR( i = 0; i < temp; i++ )
446 : {
447 35458 : IF( diff_peak_pos_te[i] != 0 )
448 : {
449 31911 : diff_peak_pos[j] = diff_peak_pos_te[i];
450 31911 : move16();
451 31911 : j = add( j, 1 );
452 : }
453 : }
454 4221 : temp = j;
455 4221 : move16();
456 :
457 : /* harmonic estimation analysis to perform BWE Reconstruction */
458 4221 : IF( *flag_dis )
459 : {
460 4221 : sharp = 0;
461 4221 : move16();
462 4221 : k = 0;
463 4221 : move16();
464 4221 : k1 = 0;
465 4221 : move16();
466 4221 : sharp1 = 0;
467 4221 : move16();
468 4221 : k2 = 0;
469 4221 : move16();
470 :
471 4221 : q = 1;
472 4221 : move16();
473 4221 : thr1 = add( min_har_pos, LR_LOWBAND_DIF_PK_LEN );
474 4221 : thr2 = add( min_har_pos, shl( LR_LOWBAND_DIF_PK_LEN, 1 ) );
475 36132 : FOR( i = 0; i < temp; i++ )
476 : {
477 31911 : test();
478 31911 : test();
479 31911 : IF( LE_16( diff_peak_pos[i], thr1 ) && diff_peak_pos[i] > 0 )
480 : {
481 25484 : sharp = add( sharp, diff_peak_pos[i] );
482 25484 : k = add( k, 1 );
483 : }
484 6427 : ELSE IF( LE_16( diff_peak_pos[i], thr2 ) && diff_peak_pos[i] > 0 )
485 : {
486 5774 : sharp1 = add( sharp1, diff_peak_pos[i] );
487 5774 : k1 = add( k1, 1 );
488 : }
489 653 : ELSE IF( diff_peak_pos[i] > 0 )
490 : {
491 653 : k2 = add( k2, 1 );
492 : }
493 31911 : q = add( q, 1 );
494 : }
495 :
496 4221 : est_freq_har_decis_fx( har_freq_est1, har_freq_est2, sharp, sharp1, hfe_est_countk1, hfe_est_countk2, k, k1, k2, prev_frm_hfe2 );
497 :
498 4221 : blk_peak_pos_max = blk_peak_pos_te[sub( temp, 1 )];
499 4221 : move16();
500 :
501 4221 : test();
502 4221 : test();
503 4221 : IF( ( *prev_stab_hfe2 ) > 0 && ( *prev_frm_hfe2 ) > 0 && *prev_stab_hfe2 < N )
504 : {
505 0 : rem_hfe2 = sub( *har_freq_est2, extract_h( L_shl( L_mult( div_s_ss( *har_freq_est2, *prev_frm_hfe2 ), *prev_frm_hfe2 ), 15 ) ) );
506 0 : diff_posmax_hfe2 = abs_s( sub( blk_peak_pos_max, *prev_stab_hfe2 ) );
507 0 : IF( rem_hfe2 == 0 )
508 : {
509 0 : test();
510 0 : IF( LT_16( diff_posmax_hfe2, 9 ) || *har_freq_est2 == 0 )
511 : {
512 0 : blk_peak_pos_max = *prev_stab_hfe2;
513 0 : move16();
514 : }
515 : ELSE
516 : {
517 0 : q_diffpos_hfe2 = div_s_ss( diff_posmax_hfe2, *har_freq_est2 );
518 0 : q_diffpos_prevhfe2 = div_s_ss( diff_posmax_hfe2, *prev_frm_hfe2 );
519 0 : test();
520 0 : IF( LT_16( q_diffpos_hfe2, 10 ) || LT_16( q_diffpos_prevhfe2, 10 ) )
521 : {
522 0 : blk_peak_pos_max = *prev_stab_hfe2;
523 0 : move16();
524 : }
525 : ELSE
526 : {
527 0 : *prev_stab_hfe2 = blk_peak_pos_max;
528 0 : move16();
529 : }
530 : }
531 : }
532 : ELSE
533 : {
534 0 : *prev_stab_hfe2 = blk_peak_pos_max;
535 0 : move16();
536 : }
537 : }
538 : ELSE
539 : {
540 4221 : *prev_stab_hfe2 = blk_peak_pos_max;
541 4221 : move16();
542 : }
543 :
544 4221 : test();
545 4221 : if ( *har_freq_est1 == 0 || *har_freq_est2 == 0 )
546 : {
547 0 : *flag_dis = 0;
548 0 : move16();
549 : }
550 : }
551 :
552 4221 : IF( *flag_dis == 0 )
553 : {
554 0 : IF( *prev_frm_hfe2 != 0 )
555 : {
556 0 : *har_freq_est2 = *prev_frm_hfe2;
557 0 : move16();
558 : }
559 : ELSE
560 : {
561 0 : nlags = shl( 1, bits_lagIndices_mode0_Har[0] );
562 0 : nlags_half = shr( nlags, 1 );
563 0 : ct_hfsb2 = 0;
564 0 : move16();
565 0 : FOR( i = 0; i < j; i++ )
566 : {
567 0 : test();
568 0 : IF( GE_16( blk_peak_pos_te[i], sub( subband_search_offset[0], nlags_half ) ) &&
569 : LT_16( blk_peak_pos_te[i], add( add( subband_search_offset[0], sbWidth[0] ), nlags_half ) ) )
570 : {
571 0 : blk_peak_pos_hfsb2[ct_hfsb2] = blk_peak_pos_te[i];
572 0 : move16();
573 0 : ct_hfsb2 = add( ct_hfsb2, 1 );
574 : }
575 : }
576 :
577 0 : IF( GT_16( ct_hfsb2, 1 ) )
578 : {
579 0 : sum_diff = 0;
580 0 : move16();
581 0 : FOR( i = 1; i < ct_hfsb2; i++ )
582 : {
583 0 : diff_peak_pos_hfsb2[i - 1] = sub( blk_peak_pos_hfsb2[i], blk_peak_pos_hfsb2[i - 1] );
584 0 : move16();
585 0 : sum_diff = add( sum_diff, diff_peak_pos_hfsb2[i - 1] );
586 : }
587 0 : *har_freq_est2 = div_s_ss( sum_diff, ct_hfsb2 );
588 0 : move16();
589 : }
590 : ELSE
591 : {
592 0 : *har_freq_est2 = min_har_pos;
593 0 : move16();
594 : }
595 : }
596 : }
597 4221 : return blk_peak_pos_max;
598 : }
599 :
600 0 : void genhf_noise_fx(
601 : const Word16 noise_flr_fx[],
602 : /* i : Qss smoothed non tonal */ /* sspectra_diff_fx:Qss */
603 : const Word16 Qss, /* i : Q0 Q value */
604 : Word32 L_xSynth_har[],
605 : /* o : QsL hf non tonal components */ /* xSynth_har:QsL */
606 : const Word16 QsL, /* i : Q0 Q value */
607 : const Word16 *predBuf_fx,
608 : /* i : Qss smoothed tonal compone */ /* sspectra:Qss */
609 : const Word16 bands, /* i : Q0 total number of subbands in a frame */
610 : const Word16 harmonic_band, /* i : Q0 Number of LF harmonic frames */
611 : const Word16 har_freq_est2, /* i : Q0 harmonic signal parameter */
612 : const Word16 pos_max_hfe2, /* i : Q0 last pulse in core coder */
613 : Word16 *pul_res, /* o : Q0 pulse resolution */
614 : GainItem_fx pk_sf_fx[], /* o : representative region */
615 : const Word16 fLenLow, /* i : Q0 low frequency length */
616 : const Word16 fLenHigh, /* i : Q0 high frequency length */
617 : const Word16 sbWidth[], /* i : Q0 bandwidth for high bands */
618 : const Word16 lagIndices[], /* i : Q0 correlation indices for most representative */
619 : const Word16 subband_offsets[], /* i : Q0 band offsets for HF reconstruction */
620 : const Word16 subband_search_offset[] /* i : Q0 most representative regions offsets in LF */
621 : )
622 : {
623 : Word16 k, j, ii, st_pos, dst_pos;
624 : Word16 nlags[NB_SWB_SUBBANDS_HAR_SEARCH_SB];
625 : Word32 L_tmpbuf[L_FRAME32k];
626 : Word16 hfband_end[NB_SWB_SUBBANDS];
627 : Word16 rem_hfe, /*last_peakpos,*/ temp_last_peakpos, i, l, pos, res;
628 : Word16 hf_pulse_peaks_fx[160], pulse_peak_sb_fx[320]; /* Qss */
629 : Word16 st_last_peakpos;
630 : Word16 tmp_fx;
631 :
632 0 : set32_fx( L_tmpbuf, 0x0L, L_FRAME32k );
633 0 : FOR( k = 0; k < 3; k++ )
634 : {
635 0 : hfband_end[k] = add( fLenLow, subband_offsets[k + 1] );
636 0 : move16();
637 : }
638 0 : hfband_end[3] = add( fLenLow, fLenHigh );
639 0 : move16();
640 :
641 0 : tmp_fx = sub( sub( fLenLow, pos_max_hfe2 ), 1 );
642 0 : rem_hfe = div_s_ss( tmp_fx, har_freq_est2 );
643 :
644 0 : st_last_peakpos = add( pos_max_hfe2, i_mult( rem_hfe, har_freq_est2 ) );
645 :
646 0 : temp_last_peakpos = st_last_peakpos;
647 0 : move16();
648 0 : i = 0;
649 0 : move16();
650 :
651 0 : FOR( k = 0; k < 2; k++ )
652 : {
653 0 : nlags[k] = shl( 1, bits_lagIndices_mode0_Har[k] );
654 0 : move16();
655 0 : l = 0;
656 0 : move16();
657 0 : WHILE( LT_16( st_last_peakpos, add( fLenLow, subband_offsets[k] ) ) )
658 : {
659 0 : st_last_peakpos = add( st_last_peakpos, har_freq_est2 );
660 : }
661 0 : st_last_peakpos = sub( st_last_peakpos, har_freq_est2 );
662 :
663 0 : IF( k == 0 )
664 : {
665 0 : st_pos = add( sub( subband_search_offset[k], shr( nlags[k], 1 ) ), lagIndices[k] );
666 :
667 : /*Copy the LF Smoothed Noise to the HF*/
668 0 : FOR( j = 0; j < sbWidth[k]; j++ )
669 : {
670 0 : L_xSynth_har[j] = L_shl( L_deposit_l( noise_flr_fx[st_pos + j] ), sub( QsL, Qss ) );
671 0 : move32();
672 0 : L_tmpbuf[j] = L_xSynth_har[j];
673 0 : move32();
674 0 : IF( predBuf_fx[st_pos + j] != 0x0 )
675 : {
676 0 : hf_pulse_peaks_fx[l] = predBuf_fx[st_pos + j];
677 0 : move16(); /* Qss */
678 0 : l = add( l, 1 );
679 : }
680 : }
681 : }
682 : ELSE
683 : {
684 0 : st_pos = sub( add( subband_search_offset[k], shr( nlags[k], 1 ) ), lagIndices[k] );
685 0 : dst_pos = sub( st_pos, sbWidth[k] );
686 0 : ii = sbWidth[k - 1];
687 0 : move16();
688 : /*Copy the LF Smoothed Noise floor to the HF*/
689 0 : FOR( j = st_pos; j > ( dst_pos ); j-- )
690 : {
691 0 : IF( GE_16( ii, add( sbWidth[k], sbWidth[k - 1] ) ) )
692 : {
693 0 : BREAK;
694 : }
695 :
696 : /*xSynth_har[ii] = noise_flr[j];*/
697 0 : L_xSynth_har[ii] = L_shl( L_deposit_l( noise_flr_fx[j] ), sub( QsL, Qss ) );
698 0 : move32();
699 0 : L_tmpbuf[ii] = L_xSynth_har[ii];
700 0 : move32();
701 0 : IF( predBuf_fx[j] != 0x0 )
702 : {
703 0 : hf_pulse_peaks_fx[l] = predBuf_fx[j];
704 0 : move16();
705 0 : l = add( l, 1 );
706 : }
707 0 : ii = add( ii, 1 );
708 : }
709 : }
710 0 : pos = 0;
711 0 : move16();
712 0 : FOR( j = 0; j < l; j++ )
713 : {
714 0 : st_last_peakpos = add( st_last_peakpos, har_freq_est2 );
715 0 : IF( LT_16( st_last_peakpos, hfband_end[k] ) )
716 : {
717 0 : pk_sf_fx[k * 8 + pos].nmrValue_fx = hf_pulse_peaks_fx[j];
718 0 : move16(); /* Qss */
719 0 : pk_sf_fx[k * 8 + pos].gainIndex_fx = sub( st_last_peakpos, fLenLow );
720 0 : move16();
721 0 : pul_res[k] = add( pul_res[k], 1 );
722 0 : move16();
723 0 : pulse_peak_sb_fx[i] = hf_pulse_peaks_fx[j];
724 0 : move16(); /* Qss */
725 0 : i = add( i, 1 );
726 0 : pos = add( pos, 1 );
727 : }
728 : }
729 0 : st_last_peakpos = temp_last_peakpos;
730 0 : move16();
731 : }
732 0 : res = sub( i, 1 );
733 0 : l = 1;
734 0 : move16();
735 0 : ii = sub( sub( hfband_end[k - 1], fLenLow ), 1 );
736 0 : tmp_fx = sub( bands, harmonic_band );
737 0 : FOR( ; k < tmp_fx; k++ )
738 : {
739 : Word16 tmp2;
740 :
741 0 : tmp2 = ( sub( hfband_end[k], fLenLow ) );
742 0 : FOR( j = sub( hfband_end[k - 1], fLenLow ); j < tmp2; j++ )
743 : {
744 0 : L_xSynth_har[j] = L_tmpbuf[ii];
745 0 : move32();
746 0 : L_tmpbuf[j] = L_xSynth_har[j];
747 0 : move32();
748 0 : ii = sub( ii, 1 );
749 : }
750 0 : pos = 0;
751 0 : move16();
752 0 : WHILE( LT_16( st_last_peakpos, hfband_end[k - 1] ) )
753 : {
754 0 : st_last_peakpos = add( st_last_peakpos, har_freq_est2 );
755 : }
756 0 : test();
757 0 : test();
758 0 : WHILE( LT_16( st_last_peakpos, hfband_end[k] ) && LT_16( pul_res[k], pul_res[2 - l] ) && LE_16( l, 2 ) )
759 : {
760 0 : test();
761 0 : test();
762 0 : pk_sf_fx[k * 8 + pos].nmrValue_fx = pulse_peak_sb_fx[res];
763 0 : move16(); /* Qss */
764 0 : pk_sf_fx[k * 8 + pos].gainIndex_fx = sub( st_last_peakpos, fLenLow );
765 0 : move16();
766 0 : pul_res[k] = add( pul_res[k], 1 );
767 0 : move16();
768 0 : res = sub( res, 1 );
769 0 : pos = add( pos, 1 );
770 0 : st_last_peakpos = add( st_last_peakpos, har_freq_est2 );
771 : }
772 0 : l = add( l, 1 );
773 : }
774 :
775 0 : return;
776 : }
777 :
778 : /*-------------------------------------------------------------------*
779 : * SmoothSpec()
780 : *
781 : * Smoothes specified samples using moving average method. The number
782 : * of points in the average is given by 'span'. Note that current
783 : * implementation does not accept 'span' to be smaller than 'fLen'.
784 : *-------------------------------------------------------------------*/
785 0 : static void SmoothSpec_fx(
786 : Word16 *inBuf, /* i : Input spectrum Q8 */
787 : Word16 *outBuf, /* o : Smoothed spectrum Q8 */
788 : Word16 num_subband /* i : subband number */
789 : )
790 : {
791 : Word16 i, tmp;
792 : Word16 span1; /* */
793 : Word16 nItems, inItems; /* inverse */
794 : Word32 L_sum; /* */
795 : Word16 *oldPtr, *newPtr; /* */
796 : Word16 hi, lo;
797 : /* ======== Q8 ======== */
798 0 : span1 = shr( MA_LEN, 1 );
799 :
800 : /*-- First sample. --*/
801 0 : L_sum = L_deposit_l( *inBuf );
802 0 : *outBuf++ = *inBuf;
803 0 : move16();
804 :
805 0 : oldPtr = inBuf;
806 0 : newPtr = inBuf + 2;
807 :
808 : /*-- Handle start. --*/
809 0 : inBuf++;
810 0 : L_sum = L_mac0( L_sum, 0x0001, *inBuf );
811 :
812 : /* nItems = 3 --> inItems = 1/3 = 0.33f, 85(Q8) */
813 : /* 1/3 = 0.3333f -> 0x2AAA Q15 */
814 0 : inItems = 0x2AAA;
815 0 : move16();
816 0 : FOR( i = 1; i < span1; i++ )
817 : {
818 0 : L_sum = L_mac0( L_sum, 0x0001, *newPtr++ );
819 :
820 0 : lo = L_Extract_lc( L_sum, &hi );
821 0 : *outBuf++ = round_fx( L_shl( Mpy_32_16( hi, lo, inItems ), 16 ) ); /* Q(8+15+1-16)=Q8 -> Q(8+16-16)=Q8 */
822 0 : move16();
823 0 : L_sum = L_mac0( L_sum, 0x0001, *newPtr++ );
824 : /* nItems += 2,
825 : * only used value is 5 -->
826 : * inItems = 1/5 = 0.2f, 51(Q8)
827 : */
828 : /* 1/5 = 0.2f -> 0x1999 Q15 */
829 0 : inItems = 0x1999;
830 0 : move16();
831 0 : inBuf++;
832 : }
833 :
834 0 : inBuf++;
835 0 : L_sum = L_mac0( L_sum, 0x0001, *newPtr++ );
836 :
837 0 : lo = L_Extract_lc( L_sum, &hi );
838 : /* 4681 (in Q15) = 0.1428 = 1/7 */
839 0 : *outBuf++ = round_fx( L_shl( Mpy_32_16( hi, lo, 4681 ), 16 ) ); /* Q(8+15+1-16)=Q8 -> Q(8+16-16)=Q8 */
840 0 : move16();
841 0 : i = add( i, 1 );
842 :
843 : /*-- Moving average. --*/
844 0 : tmp = sub( num_subband, span1 );
845 0 : FOR( ; i < tmp; i++ )
846 : {
847 0 : L_sum = L_mac0( L_sum, 0x0001, *newPtr++ );
848 0 : L_sum = L_msu0( L_sum, 0x0001, *oldPtr++ );
849 :
850 0 : lo = L_Extract_lc( L_sum, &hi );
851 : /* 4681 (in Q15) = 0.1428 = 1/7 */
852 0 : *outBuf++ = round_fx( L_shl( Mpy_32_16( hi, lo, 4681 ), 16 ) ); /* Q(8+15+1-16)=Q8 -> Q(8+16-16)=Q8 */
853 0 : move16();
854 0 : inBuf++;
855 : }
856 :
857 : /*-- Handle end. --*/
858 : /* nItems = span - 2; (nItems = 5, so we can maintain inItems = 1/5 = 0.2f from above) */
859 0 : nItems = sub( MA_LEN, 2 );
860 0 : L_sum = L_msu0( L_sum, 0x0001, *oldPtr++ );
861 :
862 0 : tmp = sub( num_subband, 1 );
863 0 : FOR( ; i < tmp; i++ )
864 : {
865 0 : L_sum = L_msu0( L_sum, 0x0001, *oldPtr++ );
866 :
867 0 : lo = L_Extract_lc( L_sum, &hi );
868 0 : *outBuf++ = round_fx( L_shl( Mpy_32_16( hi, lo, inItems ), 16 ) ); /* Q(8+15+1-16)=Q8 -> Q(8+16-16)=Q8 */
869 :
870 : /* nItems -= 2; */
871 0 : nItems = sub( nItems, 2 );
872 :
873 : /* 1.0f -> 0x7fff Q15 */
874 0 : inItems = 0x7fff;
875 0 : move16();
876 0 : if ( EQ_16( nItems, 3 ) )
877 : {
878 : /* 1/3 = 0.333f -> 0x2AAA Q15 */
879 0 : inItems = 0x2AAA;
880 0 : move16();
881 : }
882 0 : L_sum = L_msu0( L_sum, 0x0001, *oldPtr++ );
883 :
884 0 : inBuf++;
885 : }
886 :
887 : /*-- Last sample. --*/
888 0 : *outBuf = *inBuf;
889 0 : move16();
890 0 : }
891 :
892 : /*-------------------------------------------------------------------*
893 : * SpectrumSmoothing()
894 : *
895 : * Smoothing of the low-frequency envelope
896 : *-------------------------------------------------------------------*/
897 :
898 132 : void SpectrumSmoothing_fx(
899 : const Word32 *L_inBuf, /* i : Qs Low band MDCT */
900 : Word16 *outBuf_fx, /* o : Qss output */
901 : Word16 *Qss, /* o : Q0 Q value of output vector */
902 : const Word16 fLen, /* i : Q0 length */
903 : const Word16 th_cut_fx /* i : Qss threshold of cut */
904 : )
905 : {
906 : /* internal variable */
907 : Word16 i, j, k;
908 :
909 : Word16 num_subband_smooth_fx;
910 : Word16 num_subband_smooth_pre_fx;
911 :
912 : Word16 exp_normd;
913 : Word16 exp_shift;
914 :
915 : Word16 max_val_norm_fx;
916 :
917 : Word16 Qmax_val_norm[L_FRAME32k / L_SB];
918 :
919 : Word32 L_inBuf_abs;
920 : Word32 L_inBuf_pss[L_FRAME32k];
921 : Word32 L_max_val[L_FRAME32k / L_SB];
922 : Word16 outBuf_pss_fx[L_FRAME32k];
923 :
924 : Word16 m, n;
925 : Word16 cnt_zero_cont;
926 : Word16 n_list[BANDS_MAX];
927 : Word16 reset_flag;
928 : Word16 pp, pk;
929 : Word16 exp_norm;
930 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
931 132 : Flag Overflow = 0;
932 132 : move32();
933 : #endif
934 :
935 132 : *Qss = 10;
936 132 : move16();
937 132 : num_subband_smooth_pre_fx = mult( fLen, 21845 ); /* 1/L_SB = 1/12 = 21845(Q18) Q = exp_normn-18 */
938 132 : num_subband_smooth_fx = shr( num_subband_smooth_pre_fx, 18 - 15 );
939 132 : IF( NE_16( num_subband_smooth_pre_fx, shl( num_subband_smooth_fx, 18 - 15 ) ) )
940 : {
941 132 : num_subband_smooth_fx++;
942 : }
943 :
944 33924 : FOR( i = 0; i < fLen; i++ )
945 : {
946 33792 : L_inBuf_pss[i] = L_inBuf[i];
947 33792 : move32();
948 33792 : outBuf_pss_fx[i] = 0;
949 33792 : move16();
950 : }
951 :
952 1188 : FOR( i = fLen; i < fLen + ( num_subband_smooth_fx * L_SB - fLen ); i++ )
953 : {
954 1056 : L_inBuf_pss[i] = L_deposit_l( 0 );
955 1056 : move32();
956 1056 : outBuf_pss_fx[i] = 0;
957 1056 : move16();
958 : }
959 :
960 132 : j = 0;
961 132 : move16();
962 3036 : FOR( i = 0; i < num_subband_smooth_fx; i++ )
963 : {
964 2904 : L_max_val[i] = L_deposit_l( 0 );
965 2904 : move32();
966 37752 : FOR( k = 0; k < L_SB; k++ )
967 : {
968 34848 : L_inBuf_abs = L_abs( L_inBuf_pss[j] );
969 34848 : if ( LT_32( L_max_val[i], L_inBuf_abs ) )
970 : {
971 4786 : L_max_val[i] = L_inBuf_abs;
972 4786 : move32();
973 : }
974 :
975 34848 : j++;
976 : }
977 : }
978 :
979 : /* convert to maximum amplitude frequency log scale envelope */
980 132 : j = 0;
981 132 : move16();
982 3036 : FOR( i = 0; i < num_subband_smooth_fx; i++ )
983 : {
984 : /* max_val_norm = 10.0f / (max_val[i] + 0.001f); */
985 : /* 10.0f : 0x2800, Q10 */
986 2904 : IF( GT_32( L_max_val[i], 0x1L ) )
987 : {
988 2048 : exp_normd = norm_l( L_max_val[i] );
989 2048 : max_val_norm_fx = div_s( 0x2800, round_fx_o( L_shl_o( L_max_val[i], exp_normd, &Overflow ), &Overflow ) ); /* Q10-(Qs+exp_normd-16) */
990 2048 : Qmax_val_norm[i] = sub( 10 - 12 + 16 + 15, exp_normd );
991 2048 : move16(); /* 10 - (12+exp_normd-16) +15 */
992 : ;
993 : }
994 : ELSE
995 : {
996 856 : max_val_norm_fx = 0;
997 856 : move16();
998 856 : Qmax_val_norm[i] = 0;
999 856 : move16();
1000 : }
1001 :
1002 2904 : exp_shift = sub( *Qss, add( Qmax_val_norm[i], -19 ) );
1003 37752 : FOR( k = 0; k < L_SB; k++ )
1004 : {
1005 34848 : exp_norm = norm_l( L_inBuf_pss[j] );
1006 34848 : IF( L_inBuf_pss[j] == 0x0L )
1007 : {
1008 20763 : outBuf_pss_fx[j] = 0;
1009 20763 : move16();
1010 : }
1011 14085 : ELSE IF( LT_32( L_abs( L_inBuf_pss[j] ), L_max_val[i] ) )
1012 : {
1013 11792 : IF( L_inBuf_pss[j] >= 0 )
1014 : {
1015 5856 : outBuf_pss_fx[j] = round_fx_o( L_shl_o( Mpy_32_16_r( L_shl_o( L_inBuf_pss[j], exp_norm, &Overflow ), max_val_norm_fx ), sub( exp_shift, exp_norm ), &Overflow ), &Overflow );
1016 5856 : move32();
1017 : }
1018 : ELSE
1019 : {
1020 5936 : outBuf_pss_fx[j] = negate( round_fx_o( L_shl_o( Mpy_32_16_r( L_shl_o( L_abs( L_inBuf_pss[j] ), exp_norm, &Overflow ), max_val_norm_fx ), sub( exp_shift, exp_norm ), &Overflow ), &Overflow ) );
1021 5936 : move16();
1022 : }
1023 : }
1024 : ELSE
1025 : {
1026 : /* CLIP, for avoiding computational difference */
1027 2293 : outBuf_pss_fx[j] = 0x2800;
1028 2293 : move16();
1029 2293 : if ( L_inBuf_pss[j] < 0x0L )
1030 : {
1031 1126 : outBuf_pss_fx[j] = -0x2800;
1032 1126 : move16();
1033 : }
1034 : }
1035 34848 : j++;
1036 : }
1037 : }
1038 :
1039 132 : k = 0;
1040 132 : move16();
1041 132 : m = 0;
1042 132 : move16();
1043 132 : n = 0;
1044 132 : move16();
1045 132 : reset_flag = 0;
1046 132 : move16();
1047 132 : n_list[0] = 0;
1048 132 : move16();
1049 3036 : FOR( j = 0; j < num_subband_smooth_fx; j++ )
1050 : {
1051 2904 : cnt_zero_cont = 0;
1052 2904 : move16();
1053 37752 : FOR( i = 0; i < L_SB; i++ )
1054 : {
1055 34848 : cnt_zero_cont = add( cnt_zero_cont, 1 );
1056 34848 : if ( outBuf_pss_fx[k] != 0 )
1057 : {
1058 14085 : cnt_zero_cont = 0;
1059 14085 : move16();
1060 : }
1061 34848 : k = add( k, 1 );
1062 : }
1063 :
1064 2904 : IF( cnt_zero_cont != 0 )
1065 : {
1066 1777 : test();
1067 1777 : IF( GT_16( j, div_s_ss( subband_search_offsets[0], L_SB ) ) && reset_flag == 0 )
1068 : {
1069 132 : n = 0;
1070 132 : move16();
1071 132 : reset_flag = 1;
1072 132 : move16();
1073 : }
1074 1777 : n_list[n] = j;
1075 1777 : move16();
1076 1777 : n = add( n, 1 );
1077 : }
1078 :
1079 2904 : test();
1080 2904 : if ( EQ_16( reset_flag, 1 ) && EQ_16( n, 1 ) )
1081 : {
1082 255 : m = 0;
1083 255 : move16();
1084 : }
1085 :
1086 2904 : pk = sub( k, L_SB );
1087 2904 : IF( GT_16( cnt_zero_cont, mult_r( L_SB, 24576 ) ) ) /* cnt_zero_cont > 3*L_SB/4 */
1088 : {
1089 937 : pp = round_fx( L_shl( L_mult( n_list[m], L_SB ), 15 ) );
1090 12181 : FOR( i = 0; i < L_SB; i++ )
1091 : {
1092 11244 : if ( outBuf_pss_fx[pk + i] == 0 )
1093 : {
1094 11151 : outBuf_pss_fx[pk + i] = shr( outBuf_pss_fx[pp + i], 1 );
1095 11151 : move16();
1096 : }
1097 : }
1098 937 : m = add( m, 1 );
1099 : }
1100 : }
1101 :
1102 33924 : FOR( i = 0; i < fLen; i++ )
1103 : {
1104 33792 : outBuf_fx[i] = 0x0;
1105 33792 : move16();
1106 33792 : if ( GT_16( abs_s( outBuf_pss_fx[i] ), th_cut_fx ) )
1107 : {
1108 15620 : outBuf_fx[i] = outBuf_pss_fx[i];
1109 15620 : move16();
1110 : }
1111 : }
1112 :
1113 132 : return;
1114 : }
1115 :
1116 : /*-------------------------------------------------------------------*
1117 : * Get20Log10Spec()
1118 : *
1119 : * Calculates 20*log10() for the specified samples. Input and output buffers can be the same.
1120 : *-------------------------------------------------------------------*/
1121 :
1122 0 : void Get20Log10Spec_fx(
1123 : const Word32 *L_inBuf,
1124 : /* i : input Q_inBuf */ /* L_inBuf >=0, so L_abs is omitted. */
1125 : Word16 *outBuf_fx, /* o : output Q7 */
1126 : const Word16 fLen, /* i : loop length */
1127 : const Word16 Q_inBuf /* i : Qvalue of L_inBuf */
1128 : )
1129 : {
1130 : Word16 i;
1131 : Word16 exp, frac;
1132 :
1133 : Word32 L_tmp;
1134 :
1135 : Word32 L_lamda;
1136 : Word16 Q_inBuf_1;
1137 :
1138 0 : Q_inBuf_1 = sub( Q_inBuf, 1 );
1139 0 : L_lamda = L_shl( 1L, Q_inBuf_1 ); /* +1 : Q_inBuf -> Q_inBuf-1 for overflow problem */
1140 :
1141 0 : FOR( i = 0; i < fLen; i++ )
1142 : {
1143 : /*outBuf++ = (float) (20.0f * log10(fabs(*inBuf + 1.0))); */
1144 0 : L_tmp = L_add( L_shr( *L_inBuf++, 1 ), L_lamda );
1145 0 : exp = 31;
1146 0 : move16();
1147 0 : if ( L_tmp != 0x0L )
1148 : {
1149 0 : exp = norm_l( L_tmp );
1150 : }
1151 0 : frac = Log2_norm_lc( L_shl( L_tmp, exp ) );
1152 0 : exp = sub( 30, exp );
1153 0 : exp = sub( exp, Q_inBuf_1 );
1154 0 : L_tmp = L_Comp( exp, frac );
1155 :
1156 0 : L_tmp = Mpy_32_16_1( L_tmp, 24660 ); /* 6.0206 in Q12 */
1157 0 : L_tmp = L_shl( L_tmp, 2 + 8 ); /* Q7 */
1158 0 : *outBuf_fx++ = round_fx( L_tmp );
1159 0 : move16();
1160 : }
1161 :
1162 0 : return;
1163 : }
1164 : /*-------------------------------------------------------------------*
1165 : * convert_lagIndices_pls2smp()
1166 : *
1167 : *
1168 : *-------------------------------------------------------------------*/
1169 66 : void convert_lagIndices_pls2smp_fx(
1170 : Word16 lagIndices_in_fx[],
1171 : Word16 nBands_search_fx,
1172 : Word16 lagIndices_out_fx[],
1173 : const Word16 sspectra_fx[],
1174 : const Word16 sbWidth_fx[],
1175 : const Word16 fLenLow_fx )
1176 : {
1177 : Word16 sb;
1178 : Word16 i, cnt;
1179 :
1180 330 : FOR( sb = 0; sb < nBands_search_fx; sb++ )
1181 : {
1182 264 : cnt = 0;
1183 264 : move16();
1184 264 : i = 0;
1185 264 : move16();
1186 :
1187 2535 : WHILE( LE_16( cnt, lagIndices_in_fx[sb] ) )
1188 : {
1189 2271 : if ( sspectra_fx[subband_search_offsets[sb] + i] != 0 )
1190 : {
1191 615 : cnt = add( cnt, 1 );
1192 : }
1193 :
1194 2271 : i = add( i, 1 );
1195 :
1196 2271 : IF( GE_16( add( subband_search_offsets[sb], add( i, sbWidth_fx[sb] ) ), fLenLow_fx ) )
1197 : {
1198 0 : BREAK;
1199 : }
1200 : }
1201 :
1202 264 : lagIndices_out_fx[sb] = add( sub( i, 1 ), subband_search_offsets[sb] );
1203 264 : move16();
1204 : }
1205 :
1206 66 : return;
1207 : }
1208 :
1209 : /*-------------------------------------------------------------------*
1210 : * get_usebit_npswb()
1211 : *
1212 : *
1213 : *-------------------------------------------------------------------*/
1214 66 : Word16 get_usebit_npswb_fx(
1215 : Word16 hqswb_clas_fx )
1216 : {
1217 : Word16 i;
1218 : Word16 bits;
1219 : Word16 up_lmt;
1220 : const Word16 *bits_req;
1221 :
1222 66 : up_lmt = 0;
1223 66 : move16();
1224 66 : bits_req = bits_lagIndices_modeNormal;
1225 66 : move16();
1226 66 : bits = 0;
1227 66 : move16();
1228 :
1229 66 : IF( EQ_16( hqswb_clas_fx, HQ_NORMAL ) )
1230 : {
1231 66 : up_lmt = NB_SWB_SUBBANDS;
1232 66 : move16();
1233 66 : bits_req = bits_lagIndices_modeNormal;
1234 66 : move16();
1235 : }
1236 0 : ELSE IF( EQ_16( hqswb_clas_fx, HQ_HARMONIC ) )
1237 : {
1238 0 : up_lmt = NB_SWB_SUBBANDS_HAR_SEARCH_SB;
1239 0 : move16();
1240 0 : bits_req = bits_lagIndices_mode0_Har;
1241 0 : move16();
1242 0 : bits = 2;
1243 0 : move16(); /*noise gain*/
1244 : }
1245 :
1246 330 : FOR( i = 0; i < up_lmt; i++ )
1247 : {
1248 264 : bits = add( bits, bits_req[i] );
1249 264 : move16();
1250 : }
1251 :
1252 66 : return bits;
1253 : }
1254 : /*-------------------------------------------------------------------*
1255 : * SpectrumSmoothing_nss()
1256 : *
1257 : *
1258 : *-------------------------------------------------------------------*/
1259 0 : void SpectrumSmoothing_nss_fx(
1260 : const Word32 *L_inBuf, /* i : lowband MDCT */
1261 : Word16 *outBuf_fx, /* o : output */
1262 : Word16 *Qss, /* o : Q value of output vector */
1263 : const Word16 fLen /* i : length */
1264 : )
1265 : {
1266 : /* internal variable */
1267 : Word16 i, k;
1268 :
1269 : Word16 inBuf_fx[L_FRAME32k];
1270 : Word16 Qm;
1271 : Word32 L_tmp[L_FRAME32k];
1272 :
1273 : Word16 num_subband_smooth_fx;
1274 : Word16 exp_tmp;
1275 :
1276 : Word16 inBufw_fx[L_FRAME32k + L_SB_NSS];
1277 : Word16 outBufw_fx[L_FRAME32k + L_SB_NSS];
1278 : Word32 L_outBufw[L_FRAME32k + L_SB_NSS];
1279 : Word16 Qo[NUM_SUBBAND_SMOOTH_MAX];
1280 :
1281 : Word16 avg_val_fx;
1282 : Word32 L_avg_val;
1283 : Word16 r0_fx;
1284 : Word32 L_r0;
1285 : Word32 L_temp;
1286 : Word16 temp_fx;
1287 :
1288 : Word16 max_peak_fx;
1289 :
1290 : Word16 smr_fx;
1291 : Word32 L_smr;
1292 :
1293 : Word32 L_temp_sum_1[NUM_SUBBAND_SMOOTH_MAX];
1294 : Word32 L_temp_sum_2[NUM_SUBBAND_SMOOTH_MAX];
1295 : Word32 L_temp_sum_3[NUM_SUBBAND_SMOOTH_MAX];
1296 :
1297 :
1298 : Word16 temp_sum_smooth_fx[NUM_SUBBAND_SMOOTH_MAX];
1299 : Word16 temp_sum_div_fx[NUM_SUBBAND_SMOOTH_MAX];
1300 : Word16 Qsumdiv[NUM_SUBBAND_SMOOTH_MAX];
1301 : Word32 L_temp1;
1302 : Word16 temp_hi;
1303 : Word16 temp_lo;
1304 :
1305 :
1306 : Word16 avg_val2_fx;
1307 : Word32 L_avg_val2;
1308 : Word16 Qavg_val;
1309 : Word16 Qsmr;
1310 : Word16 exp, frac;
1311 :
1312 : Word16 clip_cof_fx;
1313 :
1314 : Word16 thre_fx, thre_fx_neg;
1315 : Word16 thre_min_fx;
1316 :
1317 : Word16 temp_sum_log_fx[NUM_SUBBAND_SMOOTH_MAX];
1318 : Word16 exp_norm;
1319 : Word16 exp_normn;
1320 : Word16 exp_normd;
1321 : Word16 exp_shift;
1322 :
1323 0 : L_tmp[0] = L_deposit_l( 0 );
1324 0 : move32();
1325 0 : FOR( i = 0; i < fLen; i++ )
1326 : {
1327 0 : L_tmp[0] = L_or( L_tmp[0], L_abs( L_inBuf[i] ) );
1328 0 : move32();
1329 : }
1330 0 : exp_norm = norm_l( L_tmp[0] );
1331 0 : Qm = sub( exp_norm, 4 ); /* Qm = sub(add(12, exp_norm), 16); */
1332 :
1333 0 : FOR( i = 0; i < fLen; i++ )
1334 : {
1335 0 : L_tmp[i] = L_shl( L_inBuf[i], exp_norm ); /* Q(12+exp_norm) */
1336 0 : move32();
1337 0 : inBuf_fx[i] = round_fx( L_tmp[i] ); /* Qm */
1338 0 : move16();
1339 : }
1340 :
1341 0 : num_subband_smooth_fx = shr( fLen, 3 ); /* L_SB_NSS=8 shr(target, 3); */
1342 :
1343 : /* buffer copy for fractional point */
1344 0 : FOR( i = 0; i < fLen; i++ )
1345 : {
1346 0 : inBufw_fx[i] = inBuf_fx[i];
1347 0 : move16();
1348 0 : outBufw_fx[i] = 0;
1349 0 : move16();
1350 : }
1351 :
1352 : /* initialization of over buffer for fractional point */
1353 0 : k = add( fLen, L_SB_NSS );
1354 0 : FOR( i = fLen; i < k; i++ )
1355 : {
1356 0 : inBufw_fx[i] = 0;
1357 0 : move16();
1358 0 : outBufw_fx[i] = 0;
1359 0 : move16();
1360 : }
1361 :
1362 0 : L_avg_val = L_deposit_l( 0 );
1363 0 : FOR( i = 0; i < fLen; i++ )
1364 : {
1365 0 : L_r0 = L_abs( L_deposit_l( inBufw_fx[i] ) );
1366 0 : L_avg_val = L_add( L_avg_val, L_r0 );
1367 : }
1368 0 : exp_normn = norm_l( L_avg_val );
1369 0 : exp_normn = sub( exp_normn, 1 );
1370 0 : exp_normd = norm_s( fLen );
1371 0 : avg_val_fx = div_l( L_shl( L_avg_val, exp_normn ), shl( fLen, exp_normd ) ); /* (Qs+exp_norm+exp_normn) - (exp_normd) - 15 */
1372 0 : Qavg_val = sub( add( Qm, sub( exp_normn, exp_normd ) ), 1 );
1373 :
1374 0 : max_peak_fx = 0;
1375 0 : move16();
1376 0 : FOR( i = 0; i < fLen; i++ )
1377 : {
1378 0 : r0_fx = abs_s( inBufw_fx[i] );
1379 0 : if ( LT_16( max_peak_fx, r0_fx ) )
1380 : {
1381 0 : max_peak_fx = r0_fx;
1382 0 : move16(); /* Qm */
1383 : }
1384 : }
1385 :
1386 : /*smr = 10.0f * (float)log10( max_peak/(avg_val + 1.0e-20) + 1.0e-20 ); */
1387 0 : exp_normn = norm_s( max_peak_fx );
1388 0 : exp_normn = sub( exp_normn, 1 );
1389 :
1390 0 : avg_val_fx = s_max( avg_val_fx, 0x1 );
1391 0 : exp_normd = norm_s( avg_val_fx );
1392 :
1393 0 : smr_fx = div_s( shl( max_peak_fx, exp_normn ), shl( avg_val_fx, exp_normd ) ); /* Q(exp_normn-exp_normd+15) */
1394 0 : exp_tmp = sub( exp_normn, exp_normd );
1395 0 : L_smr = L_deposit_h( smr_fx ); /* Q+16 -> Q(exp_normn-exp_normd+15+16) */
1396 0 : Qsmr = add( sub( add( Qm, exp_tmp ), Qavg_val ), 31 );
1397 :
1398 0 : L_temp = L_add( L_shr( L_smr, 1 ), 0x1L ); /* add minimum value */
1399 0 : exp = norm_l( L_temp );
1400 0 : frac = Log2_norm_lc( L_shl( L_temp, exp ) );
1401 0 : exp = sub( 30, exp );
1402 0 : exp = sub( exp, sub( Qsmr, 1 ) );
1403 0 : L_temp = L_Comp( exp, frac );
1404 :
1405 0 : L_temp = Mpy_32_16_1( L_temp, 12330 ); /* 3.0103 in Q12 */
1406 0 : L_temp = L_shl( L_temp, 2 + 8 ); /* Q7 */
1407 0 : smr_fx = round_fx( L_temp );
1408 :
1409 0 : FOR( i = 0; i < num_subband_smooth_fx; i++ )
1410 : {
1411 0 : L_temp_sum_1[i] = L_deposit_l( 0 );
1412 0 : L_temp_sum_2[i] = L_deposit_l( 0 );
1413 0 : move32();
1414 0 : move32();
1415 0 : FOR( k = 0; k < L_SB_NSS_HALF; k++ )
1416 : {
1417 0 : L_temp_sum_1[i] = L_add( L_temp_sum_1[i], extract_l( abs_s( inBufw_fx[k + L_SB_NSS * i] ) ) ); /* Qm */
1418 0 : move32();
1419 : }
1420 :
1421 0 : FOR( k = L_SB_NSS_HALF; k < L_SB_NSS; k++ )
1422 : {
1423 0 : L_temp_sum_2[i] = L_add( L_temp_sum_2[i], extract_l( abs_s( inBufw_fx[k + L_SB_NSS * i] ) ) ); /* Qm */
1424 0 : move32();
1425 : }
1426 :
1427 0 : L_temp_sum_1[i] = L_shr( L_temp_sum_1[i], 2 ); /* *0.25 guarantee low-side 16bit for L_temp_sum_* */
1428 0 : move32();
1429 0 : L_temp_sum_2[i] = L_shr( L_temp_sum_2[i], 2 ); /* *0.25 */
1430 0 : move32();
1431 0 : L_temp_sum_3[i] = L_mult( extract_l( L_temp_sum_1[i] ), extract_l( L_temp_sum_2[i] ) ); /* Qm*2+1 */
1432 0 : move32();
1433 :
1434 0 : IF( L_temp_sum_3[i] == 0 )
1435 : {
1436 0 : L_temp_sum_3[i] = L_shl( L_add( L_temp_sum_1[i], L_temp_sum_2[i] ), add( Qm, 1 ) ); /*Q(Qm+Qm+1) */
1437 0 : move32();
1438 : }
1439 : }
1440 :
1441 0 : exp_norm = add( shl( Qm, 1 ), 1 );
1442 0 : Get20Log10Spec_fx( L_temp_sum_3, temp_sum_log_fx, num_subband_smooth_fx, exp_norm );
1443 :
1444 : /* temp_sum_log_fx // *0.5 Q7 -> Q8 (not change) */
1445 0 : SmoothSpec_fx( temp_sum_log_fx, temp_sum_smooth_fx, num_subband_smooth_fx );
1446 :
1447 0 : FOR( i = 0; i < num_subband_smooth_fx; i++ )
1448 : {
1449 0 : L_temp1 = L_mult( temp_sum_smooth_fx[i], 1360 ); /* Q8+Q13+1=Q22, 1360(Q13) = 0.1660 = 3.321928(log2^10) * 0.05 */
1450 0 : L_temp1 = L_shr( L_temp1, 6 ); /* Q22 -> Q16 */
1451 0 : L_temp1 = L_negate( L_temp1 );
1452 0 : temp_lo = L_Extract_lc( L_temp1, &temp_hi );
1453 0 : Qsumdiv[i] = sub( 14, temp_hi );
1454 0 : move16();
1455 0 : temp_sum_div_fx[i] = extract_l( Pow2( 14, temp_lo ) ); /* Qsumdiv[i] */
1456 0 : move16();
1457 0 : exp_norm = norm_s( temp_sum_div_fx[i] );
1458 0 : temp_sum_div_fx[i] = shl( temp_sum_div_fx[i], exp_norm );
1459 0 : move16();
1460 0 : Qsumdiv[i] = add( Qsumdiv[i], exp_norm );
1461 0 : move16();
1462 : }
1463 :
1464 0 : *Qss = 31;
1465 0 : move16();
1466 0 : FOR( i = 0; i < num_subband_smooth_fx; i++ )
1467 : {
1468 0 : Qo[i] = add( add( Qm, Qsumdiv[i] ), 1 );
1469 0 : move16();
1470 0 : L_temp1 = 0x0L;
1471 0 : FOR( k = 0; k < L_SB_NSS; k++ )
1472 : {
1473 0 : L_outBufw[k + L_SB_NSS * i] = L_mult( inBufw_fx[k + L_SB_NSS * i], temp_sum_div_fx[i] );
1474 0 : move32();
1475 0 : L_temp1 = L_or( L_temp1, L_abs( L_outBufw[k + L_SB_NSS * i] ) );
1476 : }
1477 0 : exp_norm = 31;
1478 0 : if ( L_temp1 != 0x0L )
1479 : {
1480 0 : exp_norm = norm_l( L_temp1 );
1481 : }
1482 0 : FOR( k = 0; k < L_SB_NSS; k++ )
1483 : {
1484 0 : L_outBufw[k + L_SB_NSS * i] = L_shl( L_outBufw[k + L_SB_NSS * i], exp_norm );
1485 0 : move32();
1486 : }
1487 0 : Qo[i] = add( Qo[i], exp_norm );
1488 0 : move16();
1489 0 : *Qss = s_min( *Qss, Qo[i] );
1490 0 : move16();
1491 : }
1492 :
1493 0 : FOR( i = 0; i < num_subband_smooth_fx; i++ )
1494 : {
1495 0 : exp_shift = sub( *Qss, Qo[i] );
1496 0 : exp_shift = s_max( -31, exp_shift );
1497 0 : FOR( k = 0; k < L_SB_NSS; k++ )
1498 : {
1499 0 : L_outBufw[k + L_SB_NSS * i] = L_shl( L_outBufw[k + L_SB_NSS * i], exp_shift );
1500 0 : move16();
1501 0 : outBufw_fx[k + L_SB_NSS * i] = round_fx( L_outBufw[k + L_SB_NSS * i] );
1502 0 : move16();
1503 : }
1504 : }
1505 0 : *Qss = sub( *Qss, 16 );
1506 :
1507 0 : L_avg_val2 = L_deposit_l( 0 );
1508 0 : FOR( i = 0; i < fLen; i++ )
1509 : {
1510 0 : L_r0 = L_abs( L_deposit_l( outBufw_fx[i] ) );
1511 0 : L_avg_val2 = L_add( L_avg_val2, L_r0 ); /* Qss */
1512 : }
1513 :
1514 0 : exp_normn = norm_l( L_avg_val2 );
1515 0 : exp_normn = sub( exp_normn, 1 );
1516 0 : exp_normd = norm_s( fLen );
1517 0 : temp_fx = div_l( L_shl( L_avg_val2, exp_normn ), shl( fLen, exp_normd ) ); /* Q(obw+exp_normn - exp_normd) - 1 */
1518 0 : avg_val2_fx = shr( temp_fx, sub( sub( exp_normn, exp_normd ), 1 ) ); /* Qss */
1519 :
1520 : /*clip_cof = smr - 16.0f; */
1521 0 : clip_cof_fx = sub( smr_fx, 2048 ); /* 2048: 16.0f (Q7) */
1522 0 : if ( clip_cof_fx < 0 )
1523 : {
1524 0 : clip_cof_fx = 0;
1525 0 : move16();
1526 : }
1527 : /*clip_cof += 2.5f; */
1528 0 : clip_cof_fx = add( clip_cof_fx, 320 ); /* 320: 2.5f (Q7) */
1529 :
1530 0 : thre_fx = round_fx( L_shl( L_mult( avg_val2_fx, clip_cof_fx ), 8 ) ); /* Q(Qss+7+1) -> Qss */
1531 0 : thre_fx_neg = negate( thre_fx );
1532 0 : thre_min_fx = shr( avg_val2_fx, 2 ); /* *0.25f // Qss */
1533 :
1534 0 : FOR( i = 0; i < fLen; i++ )
1535 : {
1536 0 : IF( GT_16( abs_s( outBufw_fx[i] ), thre_fx ) )
1537 : {
1538 0 : temp_fx = thre_fx;
1539 0 : move16();
1540 0 : if ( outBufw_fx[i] < 0 )
1541 : {
1542 0 : temp_fx = thre_fx_neg;
1543 0 : move16();
1544 : }
1545 0 : outBufw_fx[i] = temp_fx;
1546 0 : move16();
1547 : }
1548 :
1549 0 : if ( LT_16( abs_s( outBufw_fx[i] ), thre_min_fx ) )
1550 : {
1551 0 : outBufw_fx[i] = 0;
1552 0 : move16();
1553 : }
1554 : }
1555 :
1556 0 : FOR( i = 0; i < fLen; i++ )
1557 : {
1558 0 : outBuf_fx[i] = outBufw_fx[i];
1559 0 : move16(); /* Qss */
1560 : }
1561 :
1562 0 : return;
1563 : }
1564 :
1565 : /*-------------------------------------------------------------------*
1566 : * return_bits_normal2
1567 : *
1568 : * arrange bit_budget when HQ_NORMAL
1569 : *-------------------------------------------------------------------*/
1570 :
1571 66 : void return_bits_normal2_fx(
1572 : Word16 *bit_budget_fx, /* i/o : bit budget */
1573 : const Word16 p2a_flags_fx[], /* i : HF tonal indicator */
1574 : const Word16 bands_fx, /* i : Total number of Subbands in a frame */
1575 : const Word16 bits_lagIndices_fx[] /* i : bits for lagIndices */
1576 : )
1577 : {
1578 : Word16 i;
1579 : const Word16 *p_p2a_flags_fx;
1580 :
1581 66 : p_p2a_flags_fx = &p2a_flags_fx[sub( bands_fx, NB_SWB_SUBBANDS )];
1582 330 : FOR( i = 0; i < NB_SWB_SUBBANDS; i++ )
1583 : {
1584 264 : if ( EQ_16( *p_p2a_flags_fx++, 1 ) )
1585 : {
1586 11 : *bit_budget_fx = add( *bit_budget_fx, bits_lagIndices_fx[i] );
1587 11 : move16();
1588 : }
1589 : }
1590 :
1591 66 : return;
1592 : }
1593 :
1594 : /*-------------------------------------------------------------------*
1595 : * preset_hq2_swb
1596 : *
1597 : * preset before swb_bwe_{enc,dec}_lr
1598 : *-------------------------------------------------------------------*/
1599 :
1600 66 : void preset_hq2_swb_fx(
1601 : const Word16 hqswb_clas_fx, /* i : HQ2 class information */
1602 : const Word16 band_end_fx[], /* i : band end of each SB */
1603 : Word16 *har_bands_fx, /* i/o : Number of LF harmonic bands */
1604 : Word16 p2a_bands_fx, /* i : flag for peakness */
1605 : const Word16 length_fx, /* i : processed band length */
1606 : const Word16 bands_fx, /* i : Total number of Subbands in a frame */
1607 : Word16 *lowlength_fx, /* o : lowband length */
1608 : Word16 *highlength_fx, /* o : highband length */
1609 : Word32 L_m[] /* o : MDCT */
1610 : )
1611 : {
1612 66 : IF( EQ_16( hqswb_clas_fx, HQ_HARMONIC ) )
1613 : {
1614 0 : *har_bands_fx = add( sub( bands_fx, p2a_bands_fx ), 1 );
1615 0 : move16();
1616 0 : *lowlength_fx = add( band_end_fx[*har_bands_fx - 1], 1 );
1617 0 : move16();
1618 : }
1619 : ELSE
1620 : {
1621 66 : *lowlength_fx = add( band_end_fx[bands_fx - NB_SWB_SUBBANDS - 1], 1 );
1622 66 : move16();
1623 : }
1624 :
1625 66 : *highlength_fx = sub( length_fx, *lowlength_fx );
1626 66 : move16();
1627 :
1628 66 : set32_fx( L_m, 0, length_fx );
1629 :
1630 66 : return;
1631 : }
1632 :
1633 : /*-------------------------------------------------------------------*
1634 : * preset_hq2_swb
1635 : *
1636 : * post process after swb_bwe_{enc,dec}_lr
1637 : *-------------------------------------------------------------------*/
1638 :
1639 66 : void post_hq2_swb_fx(
1640 : const Word32 L_m[], /* i : input_signal */
1641 : const Word16 lowlength_fx, /* i : lowband length */
1642 : const Word16 highlength_fx, /* i : highband length */
1643 : const Word16 hqswb_clas_fx, /* i : HQ2 class information */
1644 : const Word16 har_bands_fx, /* i : Number of LF harmonic bands */
1645 : const Word16 bands_fx, /* i : Total number of Subbands in a frame */
1646 : const Word16 p2a_flags_fx[], /* i : HF tonal indicator */
1647 : const Word16 band_start_fx[], /* i : band start of each SB */
1648 : const Word16 band_end_fx[], /* i : band end of each SB */
1649 : Word32 L_y2[], /* o : output signal */
1650 : Word16 npulses_fx[] /* i/o : Number of coded spectrum */
1651 : )
1652 : {
1653 : Word16 i, k;
1654 :
1655 : /* copy the scratch buffer to the output */
1656 66 : Copy32( &L_m[lowlength_fx], &L_y2[lowlength_fx], highlength_fx );
1657 :
1658 66 : IF( EQ_16( hqswb_clas_fx, HQ_HARMONIC ) )
1659 : {
1660 0 : k = har_bands_fx;
1661 0 : move16();
1662 : }
1663 : ELSE
1664 : {
1665 66 : k = sub( bands_fx, NB_SWB_SUBBANDS );
1666 : }
1667 :
1668 330 : FOR( ; k < bands_fx; k++ )
1669 : {
1670 264 : test();
1671 264 : IF( p2a_flags_fx[k] == 0 && npulses_fx[k] == 0 )
1672 : {
1673 19561 : FOR( i = band_start_fx[k]; i <= band_end_fx[k]; i++ )
1674 : {
1675 19315 : if ( L_y2[i] != 0 )
1676 : {
1677 19315 : npulses_fx[k] = add( npulses_fx[k], 1 );
1678 19315 : move16();
1679 : }
1680 : }
1681 : }
1682 : }
1683 :
1684 66 : return;
1685 : }
1686 :
1687 : /*--------------------------------------------------------------------------*
1688 : * GetSynthesizedSpecThinOut()
1689 : *
1690 : * Synthesize the spectrum in generic subband coding
1691 : *--------------------------------------------------------------------------*/
1692 :
1693 66 : void GetSynthesizedSpecThinOut_fx(
1694 : const Word16 *predBuf_fx, /* i : Qss: prediction buffer (i.e., lowband) */
1695 : const Word16 Qss, /* i : Q value of input vector */
1696 : Word32 *L_outBuf, /* o : QsL: synthesized spectrum */
1697 : Word16 QsL, /* o : Q value of synthesized spectrum */
1698 : const Word16 nBands_fx, /* i : Q0: number of subbands calculated */
1699 : const Word16 *sbWidth_fx, /* i : Q0: subband lengths */
1700 : const Word16 *lagIndices_fx, /* i : Q0: lowband index for each subband */
1701 : const Word16 *lagGains_fx, /* i : Qgain: lagGain for each subband */
1702 : const Word16 *QlagGains_fx, /* i : Q0: Q value of lagGains_fx */
1703 : const Word16 predBufLen_fx /* i : Q0: lowband length */
1704 : )
1705 : {
1706 : Word16 i, sb;
1707 : Word16 fLen_fx, lag_fx;
1708 :
1709 : const Word16 *ptr_predBuf_fx;
1710 : Word32 *ptr_L_outBuf;
1711 : Word32 *ptr_L_in_outBuf;
1712 :
1713 : Word16 exp_shift;
1714 :
1715 66 : ptr_L_in_outBuf = L_outBuf;
1716 66 : ptr_L_outBuf = L_outBuf;
1717 :
1718 330 : FOR( sb = 0; sb < nBands_fx; sb++ )
1719 : {
1720 264 : fLen_fx = sbWidth_fx[sb];
1721 264 : lag_fx = lagIndices_fx[sb];
1722 264 : move16();
1723 264 : move16();
1724 264 : if ( GT_16( add( lag_fx, fLen_fx ), predBufLen_fx ) )
1725 : {
1726 : /* should never happen */
1727 0 : lag_fx = sub( predBufLen_fx, fLen_fx );
1728 : }
1729 264 : ptr_predBuf_fx = predBuf_fx + lag_fx;
1730 :
1731 :
1732 264 : exp_shift = sub( add( add( Qss, QlagGains_fx[sb] ), 1 ), QsL );
1733 :
1734 20856 : FOR( i = 0; i < fLen_fx; i++ )
1735 : {
1736 20592 : IF( *ptr_predBuf_fx >= 0x0L )
1737 : {
1738 10189 : *ptr_L_outBuf++ = L_shr( L_mult( *ptr_predBuf_fx++, lagGains_fx[sb] ), exp_shift );
1739 10189 : move32(); /* Qss+QlagGains+1 -> QsL */
1740 : }
1741 : ELSE
1742 : {
1743 10403 : *ptr_L_outBuf++ = L_negate( L_shr( L_mult( abs_s( *ptr_predBuf_fx++ ), lagGains_fx[sb] ), exp_shift ) );
1744 10403 : move32(); /* Qss+QlagGains+1 -> QsL */
1745 : }
1746 : }
1747 : }
1748 :
1749 66 : ptr_L_outBuf = ptr_L_in_outBuf;
1750 :
1751 66 : return;
1752 : }
1753 :
1754 : /*--------------------------------------------------------------------------*
1755 : * div_s_ss
1756 : *
1757 : * compute division with Word16 Q0. ex. 10/2 -> 5
1758 : *--------------------------------------------------------------------------*/
1759 :
1760 16426 : Word16 div_s_ss( /* o: result of division (Word16 Q0) */
1761 : const Word16 n, /* i: numerator (Word16 Q0 */
1762 : const Word16 d /* i: denominator (Word16 Q0) */
1763 : )
1764 : {
1765 : Word16 norm_n, norm_d;
1766 : Word16 ns, ds;
1767 : Word16 res;
1768 :
1769 16426 : test();
1770 16426 : IF( n == 0 || d == 0 )
1771 : {
1772 1777 : return 0;
1773 : }
1774 :
1775 14649 : norm_n = norm_s( n );
1776 14649 : norm_n = sub( norm_n, 1 );
1777 14649 : ns = shl( n, norm_n );
1778 :
1779 14649 : norm_d = norm_s( d );
1780 14649 : ds = shl( d, norm_d );
1781 :
1782 14649 : res = shr( div_s( ns, ds ), add( sub( norm_n, norm_d ), 15 ) );
1783 :
1784 14649 : return res;
1785 : }
1786 : /*-------------------------------------------------------------------*
1787 : * hf_parinitiz()
1788 : *
1789 : *
1790 : *-------------------------------------------------------------------*/
1791 66 : void hf_parinitiz_fx(
1792 : const Word32 L_total_brate,
1793 : const Word16 hqswb_clas_fx,
1794 : Word16 lowlength_fx,
1795 : Word16 highlength_fx,
1796 : Word16 wBands_fx[],
1797 : const Word16 **subband_search_offset_fx,
1798 : const Word16 **subband_offsets_fx,
1799 : Word16 *nBands_fx,
1800 : Word16 *nBands_search_fx,
1801 : Word16 *swb_lowband_fx,
1802 : Word16 *swb_highband_fx )
1803 : {
1804 66 : *swb_lowband_fx = lowlength_fx;
1805 66 : move16();
1806 66 : *swb_highband_fx = highlength_fx;
1807 66 : move16();
1808 :
1809 66 : IF( EQ_16( hqswb_clas_fx, HQ_HARMONIC ) )
1810 : {
1811 : /* Mode dependent initializations (performed every frame in case mode-switching implemented) */
1812 0 : *nBands_fx = NB_SWB_SUBBANDS_HAR;
1813 0 : move16();
1814 0 : *nBands_search_fx = NB_SWB_SUBBANDS_HAR_SEARCH_SB;
1815 0 : move16();
1816 :
1817 0 : IF( EQ_32( L_total_brate, HQ_13k20 ) )
1818 : {
1819 0 : wBands_fx[0] = SWB_SB_BW_LEN0_12KBPS_HAR;
1820 0 : move16();
1821 0 : wBands_fx[1] = SWB_SB_BW_LEN1_12KBPS_HAR;
1822 0 : move16();
1823 0 : wBands_fx[2] = SWB_SB_BW_LEN2_12KBPS_HAR;
1824 0 : move16();
1825 0 : wBands_fx[3] = SWB_SB_BW_LEN3_12KBPS_HAR;
1826 0 : move16();
1827 0 : *subband_offsets_fx = subband_offsets_sub5_13p2kbps_Har;
1828 0 : move16();
1829 0 : *subband_search_offset_fx = subband_search_offsets_13p2kbps_Har;
1830 0 : move16();
1831 : }
1832 : ELSE
1833 : {
1834 0 : wBands_fx[0] = SWB_SB_BW_LEN0_16KBPS_HAR;
1835 0 : move16();
1836 0 : wBands_fx[1] = SWB_SB_BW_LEN1_16KBPS_HAR;
1837 0 : move16();
1838 0 : wBands_fx[2] = SWB_SB_BW_LEN2_16KBPS_HAR;
1839 0 : move16();
1840 0 : wBands_fx[3] = SWB_SB_BW_LEN3_16KBPS_HAR;
1841 0 : move16();
1842 0 : *subband_offsets_fx = subband_offsets_sub5_16p4kbps_Har;
1843 0 : move16();
1844 0 : *subband_search_offset_fx = subband_search_offsets_16p4kbps_Har;
1845 0 : move16();
1846 : }
1847 : }
1848 : ELSE
1849 : {
1850 : /* Mode-dependent initializations (performed every frame in case mode-switching implemented) */
1851 66 : *nBands_fx = NB_SWB_SUBBANDS;
1852 66 : move16();
1853 66 : *nBands_search_fx = NB_SWB_SUBBANDS;
1854 66 : move16();
1855 :
1856 66 : IF( EQ_32( L_total_brate, HQ_13k20 ) )
1857 : {
1858 66 : wBands_fx[0] = SWB_SB_LEN0_12KBPS;
1859 66 : move16();
1860 66 : wBands_fx[1] = SWB_SB_LEN1_12KBPS;
1861 66 : move16();
1862 66 : wBands_fx[2] = SWB_SB_LEN2_12KBPS;
1863 66 : move16();
1864 66 : wBands_fx[3] = SWB_SB_LEN3_12KBPS;
1865 66 : move16();
1866 66 : *subband_offsets_fx = subband_offsets_12KBPS;
1867 66 : move16();
1868 : }
1869 : ELSE
1870 : {
1871 0 : wBands_fx[0] = SWB_SB_LEN0_16KBPS;
1872 0 : move16();
1873 0 : wBands_fx[1] = SWB_SB_LEN1_16KBPS;
1874 0 : move16();
1875 0 : wBands_fx[2] = SWB_SB_LEN2_16KBPS;
1876 0 : move16();
1877 0 : wBands_fx[3] = SWB_SB_LEN3_16KBPS;
1878 0 : move16();
1879 0 : *subband_offsets_fx = subband_offsets_16KBPS;
1880 0 : move16();
1881 : }
1882 : }
1883 :
1884 66 : return;
1885 : }
1886 :
1887 66 : void GetlagGains_fx(
1888 : const Word16 *predBuf_fx, /* i: Qss Low freq. Smoothed Spectrum */
1889 : const Word16 Qss, /* i: Q0 Q value of predBuf */
1890 : const Word32 *L_band_energy, /* i: Qbe Band Energy */
1891 : const Word16 Qbe, /* i: Q0 Q value of band energy */
1892 : const Word16 nBands, /* i: Q0 number of SWB subbands */
1893 : const Word16 *sbWidth, /* i: Q0 width of SWB subbands */
1894 : const Word16 *lagIndices, /* i: Q0 lagIndices */
1895 : const Word16 predBufLen, /* i: Q0 length of predBuf */
1896 : Word16 *lagGains_fx, /* o: QlagGains lagGains */
1897 : Word16 *QlagGains /* o: Q0 Q value of lagGains */
1898 : )
1899 : {
1900 : Word16 i;
1901 : Word16 sb, fLen, lag;
1902 :
1903 : Word32 L_outBuf[L_FRAME32k];
1904 :
1905 : Word16 *ptr_ssBuf_fx;
1906 : Word32 L_lagEnergy;
1907 : Word16 Qene;
1908 :
1909 : Word16 temp_lo_fx, temp_hi_fx;
1910 : Word16 pow_fx;
1911 : Word16 Qpow;
1912 : Word16 exp_normd, exp_normn;
1913 : Word16 Qdiv;
1914 : Word16 exp_norm;
1915 :
1916 : Word16 temp_fx;
1917 : Word32 L_temp;
1918 :
1919 : Word16 ssBuf_fx[L_FRAME32k];
1920 : Word16 exp_norm_ss;
1921 :
1922 66 : exp_norm_ss = 2;
1923 66 : move16();
1924 16962 : FOR( i = 0; i < predBufLen; i++ )
1925 : {
1926 16896 : ssBuf_fx[i] = shr( predBuf_fx[i], exp_norm_ss );
1927 16896 : move16(); /* Qss+exp_norm_ss */
1928 : }
1929 :
1930 330 : FOR( sb = 0; sb < nBands; sb++ )
1931 : {
1932 264 : fLen = sbWidth[sb];
1933 264 : move16();
1934 264 : lag = lagIndices[sb];
1935 264 : move16();
1936 :
1937 264 : IF( GT_16( add( lag, fLen ), predBufLen ) )
1938 : {
1939 : /* should never happen */
1940 0 : lag = sub( predBufLen, fLen );
1941 0 : move16();
1942 : }
1943 :
1944 264 : GetPredictedSignal_fx( predBuf_fx, L_outBuf, lag, fLen, 0x7fff, 15 );
1945 :
1946 264 : ptr_ssBuf_fx = ssBuf_fx + lag;
1947 264 : L_lagEnergy = L_deposit_l( 0 );
1948 20856 : FOR( i = 0; i < fLen; i++ )
1949 : {
1950 20592 : L_lagEnergy = L_mac( L_lagEnergy, *ptr_ssBuf_fx, *ptr_ssBuf_fx ); /* (Qss-exp_norm_ss)*2+1 */
1951 20592 : ptr_ssBuf_fx++;
1952 : }
1953 264 : Qene = add( shl( sub( Qss, exp_norm_ss ), 1 ), 1 );
1954 :
1955 264 : IF( L_lagEnergy != 0x0L )
1956 : {
1957 : /* lagGains[sb] = (float)sqrt( pow(2.0f, band_energy[sb]) / lagEnergy ); */
1958 : /* Pow part (pow(2.0f, band_energy) ) */
1959 264 : L_temp = L_shr( L_band_energy[sb], sub( Qbe, 16 ) ); /* Qbe -> Q16 */
1960 264 : temp_lo_fx = L_Extract_lc( L_temp, &temp_hi_fx );
1961 264 : Qpow = sub( 14, temp_hi_fx );
1962 264 : pow_fx = extract_l( Pow2( 14, temp_lo_fx ) ); /* Qpow */
1963 :
1964 : /* Div part ( pow (2.0f, band_energy[i])/lagEenegy ) */
1965 264 : exp_normn = norm_s( pow_fx );
1966 264 : exp_normn = sub( exp_normn, 1 );
1967 264 : exp_normd = norm_l( L_lagEnergy );
1968 264 : temp_fx = div_s( shl( pow_fx, exp_normn ), extract_h( L_shl( L_lagEnergy, exp_normd ) ) );
1969 264 : Qdiv = add( sub( add( Qpow, exp_normn ), add( Qene, exp_normd ) ), 31 );
1970 :
1971 264 : exp_norm = norm_s( temp_fx );
1972 264 : temp_fx = shl( temp_fx, exp_norm );
1973 264 : Qdiv = add( Qdiv, exp_norm );
1974 :
1975 : /* Sqrt part sqrt(pow (2.0f, band_energy[i])/lagEnergy) */
1976 264 : QlagGains[sb] = add( Qdiv, 16 );
1977 264 : move16();
1978 264 : IF( s_and( Qdiv, 1 ) == 0 ) /* Qdiv % 2 == 0 */
1979 : {
1980 134 : L_temp = Sqrt_l( L_shr( L_deposit_h( temp_fx ), 1 ), &exp_norm );
1981 134 : L_temp = L_shr( L_temp, exp_norm );
1982 134 : QlagGains[sb] = sub( shr( QlagGains[sb], 1 ), 1 );
1983 134 : move16();
1984 134 : lagGains_fx[sb] = round_fx( L_temp );
1985 134 : move16();
1986 : }
1987 : ELSE
1988 : {
1989 130 : L_temp = Sqrt_l( L_deposit_h( temp_fx ), &exp_norm );
1990 130 : L_temp = L_shr( L_temp, exp_norm );
1991 130 : QlagGains[sb] = shr( QlagGains[sb], 1 );
1992 130 : move16();
1993 130 : lagGains_fx[sb] = round_fx( L_temp );
1994 130 : move16();
1995 : }
1996 : }
1997 : ELSE
1998 : {
1999 : /* lagGains[sb] = 0.0f; */
2000 0 : lagGains_fx[sb] = 0;
2001 0 : move16();
2002 0 : QlagGains[sb] = 15;
2003 0 : move16();
2004 : }
2005 : }
2006 :
2007 66 : return;
2008 : }
2009 :
2010 : /*--------------------------------------------------------------------------*
2011 : * noise_extr_corcod()
2012 : * Spectrum normalization for the core coder
2013 : *--------------------------------------------------------------------------*/
2014 :
2015 0 : void noise_extr_corcod_fx(
2016 : Word32 L_spectra[], /* i : QsL core coder */
2017 : const Word32 L_spectra_ni[], /* i : QsL core coder with sparse filling */
2018 : Word16 sspectra_fx[], /* o : Qss Smoothed tonal information from core coder */
2019 : Word16 sspectra_diff_fx[], /* o : Qss non tonal infomration for gap filling */
2020 : Word16 sspectra_ni_fx[], /* o : Qss smoothed core coder */
2021 : const Word16 fLenLow_fx, /* i : Q0 low frequency bands width */
2022 : Word16 prev_hqswb_clas, /* i : Q0 classification information */
2023 : Word16 *prev_ni_ratio_fx, /* i : Q15 noise parameter */
2024 : Word16 *Qss /* o : Q0 Q value for sspectra_*_fx */
2025 : )
2026 : {
2027 : Word16 i, pulse_num_fx;
2028 : Word32 L_spectra_diff[L_FRAME32k]; /* QsL */
2029 : Word16 Qss_s, Qss_d;
2030 : Word16 ni_ratio_fx, ni_ratio_cur_fx, br_adj_fx; /* Q15 */
2031 : Word16 tmp_fx;
2032 : Word16 exp_normn, exp_normd, exp_shift;
2033 : Word16 exp_norm;
2034 :
2035 : /*Spectrum Smoothing for tonal signals*/
2036 0 : SpectrumSmoothing_nss_fx( L_spectra, sspectra_fx, &Qss_s, fLenLow_fx );
2037 0 : Copy( sspectra_fx, sspectra_ni_fx, fLenLow_fx );
2038 0 : tmp_fx = 0;
2039 0 : move16();
2040 0 : FOR( i = 0; i < fLenLow_fx; i++ )
2041 : {
2042 0 : tmp_fx |= abs_s( sspectra_fx[i] );
2043 0 : logic16();
2044 : }
2045 0 : exp_norm = norm_s( tmp_fx );
2046 0 : FOR( i = 0; i < fLenLow_fx; i++ )
2047 : {
2048 0 : sspectra_fx[i] = shl( sspectra_fx[i], exp_norm );
2049 0 : move16();
2050 : }
2051 0 : Qss_s = add( Qss_s, exp_norm );
2052 :
2053 : /*noise extraction*/
2054 0 : FOR( i = 0; i < fLenLow_fx; i++ )
2055 : {
2056 0 : L_spectra_diff[i] = L_sub( L_spectra_ni[i], L_spectra[i] );
2057 0 : move32();
2058 : }
2059 0 : SpectrumSmoothing_nss_fx( L_spectra_diff, sspectra_diff_fx, &Qss_d, fLenLow_fx );
2060 0 : tmp_fx = 0;
2061 0 : move16();
2062 0 : FOR( i = 0; i < fLenLow_fx; i++ )
2063 : {
2064 0 : tmp_fx |= abs_s( sspectra_diff_fx[i] );
2065 0 : logic16();
2066 : }
2067 0 : exp_norm = norm_s( tmp_fx );
2068 0 : FOR( i = 0; i < fLenLow_fx; i++ )
2069 : {
2070 0 : sspectra_diff_fx[i] = shl( sspectra_diff_fx[i], exp_norm );
2071 0 : move16();
2072 : }
2073 0 : Qss_d = add( Qss_d, exp_norm );
2074 :
2075 0 : IF( LT_16( Qss_s, Qss_d ) )
2076 : {
2077 0 : *Qss = Qss_s;
2078 0 : move16();
2079 0 : exp_shift = sub( Qss_d, *Qss );
2080 0 : FOR( i = 0; i < fLenLow_fx; i++ )
2081 : {
2082 0 : sspectra_diff_fx[i] = shr( sspectra_diff_fx[i], exp_shift );
2083 0 : move16();
2084 : }
2085 : }
2086 : ELSE
2087 : {
2088 0 : *Qss = Qss_d;
2089 0 : move16();
2090 0 : exp_shift = sub( Qss_s, *Qss );
2091 0 : FOR( i = 0; i < fLenLow_fx; i++ )
2092 : {
2093 0 : sspectra_fx[i] = shr( sspectra_fx[i], exp_shift );
2094 0 : move16();
2095 0 : sspectra_ni_fx[i] = shr( sspectra_ni_fx[i], exp_shift );
2096 0 : move16();
2097 : }
2098 : }
2099 :
2100 : /*Smoothing the noise components*/
2101 0 : br_adj_fx = 29491; /* br_adj = 0.9f; Q15 */
2102 0 : move16();
2103 0 : pulse_num_fx = 0;
2104 0 : move16();
2105 0 : FOR( i = 0; i < fLenLow_fx; i++ )
2106 : {
2107 0 : if ( L_spectra[i] != 0x0L )
2108 : {
2109 0 : pulse_num_fx = add( pulse_num_fx, 1 );
2110 : }
2111 : }
2112 :
2113 0 : ni_ratio_cur_fx = 0x0;
2114 0 : move16();
2115 0 : IF( pulse_num_fx != 0 )
2116 : {
2117 : /*ni_ratio_cur = (fLenLow-pulse_num)/(fLenLow+0.0f);*/
2118 0 : tmp_fx = sub( fLenLow_fx, pulse_num_fx );
2119 0 : exp_normn = norm_s( tmp_fx );
2120 0 : exp_normn = sub( exp_normn, 1 );
2121 0 : exp_normd = norm_s( fLenLow_fx );
2122 0 : ni_ratio_cur_fx = div_s( shl( tmp_fx, exp_normn ), shl( fLenLow_fx, exp_normd ) ); /* exp_normn - exp_normd + 15 */
2123 0 : ni_ratio_cur_fx = shl( ni_ratio_cur_fx, sub( exp_normn, exp_normd ) ); /* 15 - (exp_normn - exp-normd + 15) */
2124 :
2125 : /*ni_ratio_cur *= br_adj;*/
2126 0 : ni_ratio_cur_fx = mult_r( ni_ratio_cur_fx, br_adj_fx );
2127 : }
2128 :
2129 0 : IF( EQ_16( prev_hqswb_clas, HQ_HARMONIC ) )
2130 : {
2131 0 : IF( GT_16( ni_ratio_cur_fx, *prev_ni_ratio_fx ) )
2132 : {
2133 : /* 0.8: 26214(Q15) 0.2: 6554(Q15) */
2134 0 : ni_ratio_fx = mac_r( L_mult( ni_ratio_cur_fx, 26214 ), *prev_ni_ratio_fx, 6554 );
2135 : }
2136 : ELSE
2137 : {
2138 : /* 0.6: 19661(Q15) 0.4: 13107(Q15) */
2139 0 : ni_ratio_fx = mac_r( L_mult( ni_ratio_cur_fx, 19661 ), *prev_ni_ratio_fx, 13107 );
2140 : }
2141 : }
2142 : ELSE
2143 : {
2144 : /* 0.7: 22938(Q15) */
2145 0 : ni_ratio_fx = mult_r( ni_ratio_cur_fx, 22938 );
2146 : }
2147 0 : *prev_ni_ratio_fx = ni_ratio_fx;
2148 0 : move16();
2149 :
2150 0 : FOR( i = 0; i < fLenLow_fx; i++ )
2151 : {
2152 0 : sspectra_diff_fx[i] = mult_r( sspectra_diff_fx[i], ni_ratio_fx );
2153 0 : move16();
2154 0 : sspectra_ni_fx[i] = add( sspectra_fx[i], sspectra_diff_fx[i] );
2155 0 : move16();
2156 : }
2157 :
2158 0 : return;
2159 : }
2160 :
2161 : /*--------------------------------------------------------------------------*
2162 : * ton_ene_est()
2163 : * band energies for missing bands in the core coder
2164 : *--------------------------------------------------------------------------*/
2165 :
2166 0 : void ton_ene_est_fx(
2167 : Word32 L_xSynth_har[], /* i/o: QsL buffer with non tonal compoents */
2168 : const Word16 QsL, /* i : Q0 Q value for xSynth_har */
2169 : Word32 L_be_tonal[], /* o : QbeL tonal energy of the missing bands */
2170 : Word16 *QbeL, /* o : Q0 Q value for be_tonal */
2171 : const Word32 L_band_energy[], /* i : Qbe subband energies */
2172 : const Word16 Qbe, /* i : Q0 Q value for band_energy */
2173 : const Word16 band_start[], /* i : Q0 subband start indices */
2174 : const Word16 band_end[], /* i : Q0 subband end indices */
2175 : const Word16 band_width[], /* i : Q0 subband widths */
2176 : const Word16 fLenLow, /* i : Q0 low frequency width */
2177 : const Word16 fLenHigh, /* i : Q0 High frequency width */
2178 : const Word16 bands, /* i : Q0 total subbands */
2179 : const Word16 har_bands, /* i : Q0 total number of harmonics bands */
2180 : const Word16 ni_lvl_fx, /* i : Q11 noise enve for the hf bands */
2181 : GainItem_fx pk_sf_fx[], /* i : */
2182 : const Word16 Qss, /* i : Q0 Q value for GainItem_fx->nmrValue */
2183 : const Word16 *pul_res /* i : Q0 tonal resolution */
2184 : )
2185 : {
2186 : Word16 i, j, k;
2187 : Word16 exp_norm;
2188 : Word16 Inv_band_width_fx[BANDS_MAX];
2189 : Word16 QInvBW[BANDS_MAX];
2190 :
2191 : Word16 xSynth_har_fx[L_FRAME32k];
2192 : Word16 QxSynth; /* Q value for xSynth_har_fx */
2193 : Word16 QxSynth_sft; /* Q value for xSynth_har_fx */
2194 :
2195 : Word16 sb_ton_loc_fx[SWB_HAR_RAN1]; /* Q0 */
2196 : Word16 sb_ton_fx[SWB_HAR_RAN1]; /* Qss */
2197 : Word16 ni_gain_fx[NB_SWB_SUBBANDS];
2198 : Word16 Qni_gain;
2199 : Word16 avg_pe_fx[NB_SWB_SUBBANDS];
2200 : Word16 Qavg_pe[NB_SWB_SUBBANDS];
2201 : Word16 QsN; /* Q value for xSynth_har after multipy ni_lvl */
2202 : Word16 exp_safe; /* overflow prevent shift */
2203 :
2204 : Word16 pos, count_pos_st, count_pos_end;
2205 : Word16 pul_res_bnd[NB_SWB_SUBBANDS];
2206 : Word16 peak_fx[NB_SWB_SUBBANDS]; /* Qss */
2207 :
2208 : Word32 L_E;
2209 : Word16 QE;
2210 : Word16 temp_lo_fx, temp_hi_fx;
2211 : Word32 L_temp;
2212 : Word16 exp_pow;
2213 : Word32 L_band_energy_Linear[BANDS_MAX];
2214 :
2215 : Word16 exp_normd, exp_normn;
2216 :
2217 : Word16 E_r_fx;
2218 : Word16 QE_r; /* Q value for E_r_fx */
2219 :
2220 : Word16 exp_shift;
2221 :
2222 : Word16 E_r_shift_fx;
2223 : Word16 fac_fx;
2224 : Word16 Qtemp;
2225 : Word16 temp2_fx, Qtemp2;
2226 : Word16 temp_fx;
2227 :
2228 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2229 0 : Flag Overflow = 0;
2230 0 : move32();
2231 : #endif
2232 :
2233 0 : *QbeL = 3;
2234 0 : move16();
2235 0 : Qni_gain = 8;
2236 0 : move16();
2237 :
2238 0 : FOR( k = 0; k < bands; k++ )
2239 : {
2240 0 : exp_norm = norm_s( band_width[k] );
2241 0 : exp_norm = sub( exp_norm, 1 );
2242 0 : Inv_band_width_fx[k] = div_s( 0x1fff, shl( band_width[k], exp_norm ) ); /* */
2243 0 : QInvBW[k] = sub( 28, exp_norm ); /* 13-exp_norm+15 */
2244 0 : move16();
2245 : }
2246 :
2247 0 : set16_fx( sb_ton_loc_fx, -1, SWB_HAR_RAN1 );
2248 0 : set16_fx( ni_gain_fx, 0, NB_SWB_SUBBANDS );
2249 0 : set16_fx( avg_pe_fx, 0, NB_SWB_SUBBANDS );
2250 0 : set16_fx( Qavg_pe, 0, NB_SWB_SUBBANDS );
2251 0 : set16_fx( sb_ton_fx, 0, NB_SWB_SUBBANDS );
2252 0 : set16_fx( peak_fx, 0, NB_SWB_SUBBANDS );
2253 0 : FOR( i = 0; i < fLenHigh; i++ )
2254 : {
2255 0 : L_xSynth_har[i] = Mult_32_16( L_xSynth_har[i], ni_lvl_fx ); /* QsL(=12)+11-15=8 */
2256 0 : move32();
2257 : }
2258 0 : QsN = sub( add( QsL, 11 ), 15 );
2259 :
2260 0 : exp_safe = 4; /*move16();*/
2261 0 : move16();
2262 0 : norm_vec_32_16_scale_fx( L_xSynth_har, QsN, fLenHigh, xSynth_har_fx, &QxSynth, exp_safe );
2263 :
2264 0 : pos = 0;
2265 0 : move16();
2266 0 : i = sub( bands, har_bands );
2267 0 : FOR( k = 0; k < i; k++ )
2268 : {
2269 0 : FOR( j = 0; j < pul_res[k]; j++ )
2270 : {
2271 0 : sb_ton_loc_fx[pos] = pk_sf_fx[k * 8 + j].gainIndex_fx;
2272 0 : move16();
2273 0 : sb_ton_fx[pos] = pk_sf_fx[k * 8 + j].nmrValue_fx;
2274 0 : move16();
2275 0 : pos = add( pos, 1 );
2276 : }
2277 : }
2278 0 : k = 0;
2279 0 : move16();
2280 0 : pos = 0;
2281 0 : move16();
2282 : DO
2283 : {
2284 0 : count_pos_st = pos;
2285 0 : WHILE( sb_ton_loc_fx[pos] <= ( band_end[k + har_bands] - fLenLow ) && sb_ton_loc_fx[pos] >= 0 )
2286 : {
2287 0 : pos = add( pos, 1 );
2288 : }
2289 0 : count_pos_end = pos;
2290 0 : move16();
2291 0 : pul_res_bnd[k] = sub( count_pos_end, count_pos_st );
2292 0 : move16();
2293 0 : if ( pul_res_bnd[k] > 0 )
2294 : {
2295 0 : peak_fx[k] = abs_s( sb_ton_fx[count_pos_st] );
2296 0 : move16();
2297 : }
2298 0 : k = add( k, 1 );
2299 : }
2300 0 : WHILE( LT_16( k, NB_SWB_SUBBANDS ) );
2301 :
2302 0 : k = 0;
2303 0 : move16();
2304 : /*energy calculation for tonal components*/
2305 0 : FOR( i = har_bands; i < bands; i++ )
2306 : {
2307 0 : L_E = sum2_fx( &xSynth_har_fx[sub( band_start[i], fLenLow )], band_width[i] );
2308 0 : QE = add( shl( QxSynth, 1 ), 1 ); /* QxSynth*2+1 */
2309 :
2310 : /* E_r = (float) E/(float)pow(2.0f,band_energy[i]); -> E * pow(2.0f, -band_energy) */
2311 : /* Pow Part */
2312 0 : L_temp = L_shr( L_band_energy[i], sub( Qbe, 16 ) );
2313 0 : temp_lo_fx = L_Extract_lc( L_temp, &temp_hi_fx );
2314 :
2315 0 : exp_pow = sub( 14, temp_hi_fx );
2316 0 : L_band_energy_Linear[i] = Pow2( 14, temp_lo_fx );
2317 0 : move32(); /* Qexp_pow */
2318 0 : L_band_energy_Linear[i] = L_shl_sat( L_band_energy_Linear[i], sub( *QbeL, exp_pow ) );
2319 0 : move32();
2320 : /* Div Part */
2321 0 : E_r_fx = 0x7fff;
2322 0 : move16();
2323 0 : QE_r = 0;
2324 0 : move16();
2325 0 : IF( L_band_energy_Linear[i] != 0x0L )
2326 : {
2327 0 : exp_normd = norm_l( L_E );
2328 0 : exp_normd = sub( exp_normd, 1 );
2329 0 : exp_normn = norm_l( L_band_energy_Linear[i] );
2330 :
2331 0 : E_r_fx = div_s( extract_h( L_shl( L_E, exp_normd ) ), extract_h( L_shl( L_band_energy_Linear[i], exp_normn ) ) );
2332 : /* QE_r = (QE-16) - (QbeL+exp_normn-16) + 15; */
2333 0 : QE_r = add( sub( add( QE, exp_normd ), add( *QbeL, exp_normn ) ), 15 );
2334 : }
2335 :
2336 0 : L_E = L_shl( L_E, sub( *QbeL, QE ) );
2337 0 : QE = *QbeL;
2338 0 : move16();
2339 : /* 0.06=15729(Q18) */
2340 0 : exp_shift = sub( 18, QE_r );
2341 0 : E_r_shift_fx = shl_o( E_r_fx, exp_shift, &Overflow );
2342 0 : IF( LT_16( E_r_shift_fx, 15729 ) ) /* E_r < 0.06 */
2343 : {
2344 : /* avg_pe[k] = (float) sqrt(pow(2.0f,band_energy[i])/band_width[i]); */
2345 : /* Pre SQRT part */
2346 : /*L_temp = Mpy_32_16_1(L_band_energy_Linear[i], Inv_band_width_fx[i]);*/ /* QbeL + QInvBW -15 */
2347 0 : L_temp = Mult_32_16( L_band_energy_Linear[i], Inv_band_width_fx[i] ); /* QbeL + QInvBW -15 */
2348 0 : Qtemp = sub( add( *QbeL, QInvBW[i] ), 15 );
2349 :
2350 0 : sqrt_32n_16_fx( L_temp, Qtemp, &avg_pe_fx[k], &Qavg_pe[k] );
2351 :
2352 0 : fac_fx = 19661; /* 0.6(Q15) */
2353 0 : move16();
2354 0 : IF( pul_res_bnd[k] != 0 )
2355 : {
2356 : /* Div Part */
2357 0 : L_temp = Mult_32_16( L_E, Inv_band_width_fx[i] ); /* QE+exp_norm+QInvBW[i]+1 */
2358 0 : Qtemp = sub( add( QE, QInvBW[i] ), 15 );
2359 :
2360 : /* SQRT Part */
2361 0 : sqrt_32n_16_fx( L_temp, Qtemp, &temp2_fx, &Qtemp2 );
2362 :
2363 : /* Div Part */
2364 0 : exp_normd = norm_s( temp2_fx );
2365 0 : exp_normd = sub( exp_normd, 1 );
2366 0 : exp_normn = norm_s( peak_fx[k] );
2367 :
2368 0 : fac_fx = div_s( shl( temp2_fx, exp_normd ), shl( peak_fx[k], exp_normn ) );
2369 0 : fac_fx = shl_sat( fac_fx, sub( add( Qss, exp_normn ), add( Qtemp2, exp_normd ) ) ); /* Qtemp2+exp_normd-(Qss+exp_normn)+15 -> 15*/
2370 : }
2371 :
2372 0 : ni_gain_fx[k] = mult_r( avg_pe_fx[k], fac_fx ); /* Qavg_pe[k] */
2373 0 : move16();
2374 :
2375 0 : L_temp = L_mult( ni_gain_fx[k], ni_gain_fx[k] );
2376 0 : L_temp = Mult_32_16( L_temp, E_r_fx );
2377 :
2378 : /* 0.12f: 257698038 (Q31) */
2379 0 : if ( GE_32( L_shl_o( L_temp, sub( 31, add( add( shl( Qavg_pe[k], 1 ), QE_r ), 1 - 15 ) ), &Overflow ), 257698038 ) )
2380 : {
2381 0 : ni_gain_fx[k] = mult_r( 1638, ni_gain_fx[k] ); /* 0.05 : 1638(Q15) */
2382 0 : move16();
2383 : }
2384 0 : Overflow = 0;
2385 0 : move16();
2386 0 : ni_gain_fx[k] = shl( ni_gain_fx[k], sub( Qni_gain, Qavg_pe[k] ) );
2387 0 : move16();
2388 0 : assert( Qni_gain == 8 ); /* 358 is '(short)(1.4*pow(2,Qni_gain))' */
2389 0 : ni_gain_fx[k] = s_max( ni_gain_fx[k], 358 ); /* 1.4 -> 22938(Q14) */
2390 0 : move16();
2391 0 : exp_shift = QsL - ( QxSynth + Qni_gain + 1 ); /* QsL - (QxSynth+Qni_gain+1) */
2392 0 : FOR( j = band_start[i]; j <= band_end[i]; j++ )
2393 : {
2394 0 : L_xSynth_har[j - fLenLow] = L_shl( L_mult( xSynth_har_fx[j - fLenLow], ni_gain_fx[k] ), exp_shift ); /* QsL - (QxSynth+Qni_gain+1) */
2395 0 : move32();
2396 : }
2397 :
2398 0 : exp_safe = 4; /* move16(); */
2399 0 : move16();
2400 0 : norm_vec_32_16_scale_fx( &L_xSynth_har[band_start[i] - fLenLow], QsL, band_width[i], &xSynth_har_fx[band_start[i] - fLenLow], &QxSynth_sft, exp_safe );
2401 :
2402 0 : L_E = sum2_fx( &xSynth_har_fx[sub( band_start[i], fLenLow )], band_width[i] );
2403 0 : QE = add( shl( QxSynth_sft, 1 ), 1 );
2404 :
2405 0 : L_E = L_shl_sat( L_E, sub( *QbeL, QE ) );
2406 0 : QE = *QbeL;
2407 0 : move16();
2408 : }
2409 : ELSE
2410 : {
2411 : /* Q8 -> Q12 */
2412 0 : FOR( j = band_start[i]; j <= band_end[i]; j++ )
2413 : {
2414 0 : L_xSynth_har[j - fLenLow] = L_shl( L_xSynth_har[j - fLenLow], 4 ); /* Q8(12+11-15) -> Q12 */
2415 0 : move32();
2416 : }
2417 : }
2418 :
2419 0 : k = add( k, 1 );
2420 :
2421 0 : L_be_tonal[i] = L_sub( L_band_energy_Linear[i], L_E );
2422 0 : move32();
2423 0 : IF( L_be_tonal[i] < 0x0L )
2424 : {
2425 0 : L_E = L_deposit_l( 0 );
2426 0 : FOR( j = ( band_start[i] - fLenLow ); j <= ( band_end[i] - fLenLow ); j++ )
2427 : {
2428 0 : temp_fx = round_fx( L_shl( L_xSynth_har[j], ( *QbeL + 7 ) / 2 ) ); /* (12+x-16)*2+1 => QbeL */
2429 0 : L_xSynth_har[j] = L_shr( L_xSynth_har[j], 2 ); /* 1/4 */
2430 0 : move32();
2431 0 : L_E = L_mac( L_E, temp_fx, temp_fx );
2432 : }
2433 :
2434 0 : L_E = L_shr( L_E, 4 ); /* 1/4 */
2435 0 : L_be_tonal[i] = L_sub( L_band_energy_Linear[i], L_E );
2436 0 : move32();
2437 : }
2438 : }
2439 :
2440 0 : return;
2441 : }
2442 :
2443 :
2444 : /*--------------------------------------------------------------------------*
2445 : * Gettonl_scalfact()
2446 : * Gap filling for the core coder
2447 : *--------------------------------------------------------------------------*/
2448 0 : void Gettonl_scalfact_fx(
2449 : Word32 *L_outBuf, /* i/o: QsL synthesized spectrum */
2450 : Word16 QsL, /* i : Q0 Q value for outBuf */
2451 : const Word32 *L_codbuf, /* i : QsL core coder */
2452 : const Word16 fLenLow, /* i : Q0 lowband length */
2453 : const Word16 fLenHigh, /* i : Q0 highband length */
2454 : const Word16 harmonic_band, /* i : Q0 total number of Low frequency bands */
2455 : const Word16 bands, /* i : Q0 total number of subbands in a frame */
2456 : Word32 *L_band_energy, /* i : Qbe band energy of each subband */
2457 : Word16 Qbe, /* i : Q0 Q value for band_energy */
2458 : const Word16 *band_start, /* i : Q0 subband start indices */
2459 : const Word16 *band_end, /* i : Q0 subband end indices */
2460 : const Word16 p2aflags[], /* i : Q0 missing bands in the core coder */
2461 : Word32 L_be_tonal[], /* i : QbeL tonal energy */
2462 : Word16 QbeL, /* i : Q0 Q value for be_tonal */
2463 : GainItem_fx *pk_sf_fx, /* i : toanl information for Sparse filling */
2464 : Word16 Qss, /* i : Q0 Q value for pk_sf.nmrValue */
2465 : Word16 *pul_res_pk /* i : Q0 pulse resolution information */
2466 : )
2467 : {
2468 : Word16 i, j, tmp;
2469 : Word16 sb_ton_fx[SWB_HAR_RAN1]; /* Qss */
2470 : Word16 sb_ton_loc_fx[SWB_HAR_RAN1]; /* Q0 */
2471 : Word32 L_est_ton_ene[NB_SWB_SUBBANDS]; /* QetEne */
2472 : Word16 QetEne;
2473 : Word16 band_sf_fx[SWB_HAR_RAN1]; /* Qton_sf */
2474 : Word16 pos_fx, k_fx, pos_tmp_fx; /* Q0 */
2475 : Word16 exp_safe;
2476 : Word16 temp_fx;
2477 : Word16 Qtemp;
2478 :
2479 : Word16 band_pos_fx;
2480 : Word16 count_pos_st_fx, count_pos_end_fx;
2481 :
2482 : Word16 exp_normd, exp_normn;
2483 :
2484 : Word16 ton_sf_fx; /* Qton_sf */
2485 : Word16 Qton_sf;
2486 :
2487 : Word16 step_fx; /* Q15 */
2488 : Word32 L_temp;
2489 :
2490 : Word16 enrd_r_fx; /* Q15 */
2491 :
2492 : Word32 L_band_energy_Linear[BANDS_MAX]; /* QbeL */
2493 : Word16 temp_hi_fx, temp_lo_fx;
2494 : Word16 exp_pow;
2495 : Word16 exp_shift;
2496 :
2497 : Word16 Qbsf2[SWB_HAR_RAN1];
2498 :
2499 0 : Qton_sf = sub( sub( QsL, Qss ), 1 );
2500 :
2501 0 : enrd_r_fx = 29491;
2502 0 : move16(); /* 0.9: 29491.2(Q15) */
2503 :
2504 0 : set32_fx( L_est_ton_ene, 0x0L, NB_SWB_SUBBANDS );
2505 0 : set16_fx( sb_ton_loc_fx, -1, SWB_HAR_RAN1 );
2506 :
2507 : /* Get the tonal information for sparse filling */
2508 0 : pos_fx = 0;
2509 0 : move16();
2510 0 : FOR( k_fx = 0; k_fx < sub( bands, harmonic_band ); k_fx++ )
2511 : {
2512 0 : FOR( j = 0; j < pul_res_pk[k_fx]; j++ )
2513 : {
2514 0 : sb_ton_loc_fx[pos_fx] = pk_sf_fx[k_fx * 8 + j].gainIndex_fx;
2515 0 : move16();
2516 0 : sb_ton_fx[pos_fx] = pk_sf_fx[k_fx * 8 + j].nmrValue_fx;
2517 0 : move16();
2518 0 : pos_fx = add( pos_fx, 1 );
2519 : }
2520 : }
2521 0 : k_fx = 0;
2522 0 : move16();
2523 0 : pos_fx = 0;
2524 0 : move16();
2525 0 : pos_tmp_fx = 0;
2526 0 : move16();
2527 :
2528 : DO
2529 : {
2530 0 : band_pos_fx = add( k_fx, harmonic_band );
2531 0 : count_pos_st_fx = pos_fx;
2532 0 : move16();
2533 0 : test();
2534 0 : WHILE( LE_16( sb_ton_loc_fx[pos_fx], sub( band_end[band_pos_fx], fLenLow ) ) && sb_ton_loc_fx[pos_fx] >= 0 )
2535 : {
2536 0 : test();
2537 0 : pos_fx = add( pos_fx, 1 );
2538 : }
2539 0 : count_pos_end_fx = pos_fx;
2540 0 : move16();
2541 :
2542 0 : exp_safe = 2; /* move16(); */
2543 0 : move16();
2544 0 : QetEne = add( shl( sub( Qss, exp_safe ), 1 ), 1 );
2545 0 : L_temp = L_add( L_est_ton_ene[k_fx], 0 );
2546 0 : FOR( i = count_pos_st_fx; i < count_pos_end_fx; i++ )
2547 : {
2548 0 : temp_fx = shr( sb_ton_fx[i], exp_safe );
2549 0 : L_temp = L_mac( L_temp, temp_fx, temp_fx );
2550 : }
2551 0 : L_est_ton_ene[k_fx] = L_temp;
2552 0 : move32();
2553 :
2554 0 : IF( L_est_ton_ene[k_fx] <= 0x0L )
2555 : {
2556 : /* 1.0 */
2557 0 : L_est_ton_ene[k_fx] = L_deposit_l( MAX_16 );
2558 0 : QetEne = 15;
2559 0 : move16();
2560 : }
2561 :
2562 : /*ton_sf= (float) sqrt(be_tonal[band_pos]/est_ton_ene[k]);*/ /* be_tonal: QbeL, est_ton_ene: (Qss-exp_safe)*2+1 */
2563 : /* Div Part */
2564 0 : exp_normd = norm_l( L_be_tonal[band_pos_fx] );
2565 0 : exp_normd = sub( exp_normd, 1 );
2566 0 : exp_normn = norm_l( L_est_ton_ene[k_fx] );
2567 :
2568 0 : ton_sf_fx = 0x0;
2569 0 : move16();
2570 0 : IF( L_be_tonal[band_pos_fx] > 0x0L )
2571 : {
2572 0 : ton_sf_fx = div_l( L_shl( L_be_tonal[band_pos_fx], exp_normd ), extract_h( L_shl( L_est_ton_ene[k_fx], exp_normn ) ) ); /* QbeL+exp_normd - (QetEne+exp_normn-16) - 1 */
2573 : }
2574 :
2575 : /* Sqrt Part */
2576 : /*sqrt_32n_16_fx(L_deposit_h(ton_sf_fx), (QbeL+exp_normd)-(QetEne+exp_normn-16)-1+16, &ton_sf_fx, &Qton_sf);*/
2577 0 : sqrt_32n_16_fx( L_deposit_h( ton_sf_fx ), add( sub( add( QbeL, exp_normd ), add( QetEne, exp_normn ) ), 31 ), &ton_sf_fx, &Qton_sf );
2578 :
2579 0 : FOR( i = count_pos_st_fx; i < count_pos_end_fx; i++ )
2580 : {
2581 0 : band_sf_fx[pos_tmp_fx] = ton_sf_fx;
2582 0 : move16();
2583 0 : Qbsf2[pos_tmp_fx] = Qton_sf;
2584 0 : move16();
2585 0 : pos_tmp_fx = add( pos_tmp_fx, 1 );
2586 : }
2587 0 : k_fx = add( k_fx, 1 );
2588 : }
2589 0 : WHILE( LT_16( k_fx, NB_SWB_SUBBANDS ) );
2590 :
2591 : /* Gap filling for the core coder */
2592 : /* 0.077=20185(Q18) */
2593 0 : L_temp = L_mult( 20185, fLenHigh ); /* 18+0+1= 19 */
2594 0 : exp_normn = norm_l( L_temp );
2595 :
2596 0 : step_fx = div_s( 0x3fff, extract_h( L_shl( L_temp, exp_normn ) ) );
2597 0 : step_fx = shl( step_fx, sub( exp_normn, 11 ) ); /* 15 - (14-(19+exp_normn-16)+15) */ /* Q15 */
2598 :
2599 0 : pos_tmp_fx = 0;
2600 0 : move16();
2601 0 : tmp = sub( bands, harmonic_band );
2602 0 : FOR( k_fx = 0; k_fx < tmp; k_fx++ )
2603 : {
2604 0 : band_pos_fx = add( k_fx, harmonic_band );
2605 :
2606 0 : IF( L_be_tonal[band_pos_fx] > 0x0L )
2607 : {
2608 : /* enrd_r *=(float)sqrt(be_tonal[band_pos]/pow(2.0f,band_energy[band_pos])); */
2609 : /* Pow Part */
2610 0 : L_temp = L_shr( L_band_energy[band_pos_fx], sub( Qbe, 16 ) );
2611 0 : temp_lo_fx = L_Extract_lc( L_temp, &temp_hi_fx );
2612 0 : exp_pow = sub( 14, temp_hi_fx );
2613 0 : L_band_energy_Linear[band_pos_fx] = Pow2( 14, temp_lo_fx );
2614 0 : move32(); /* Qexp_pow */
2615 0 : L_band_energy_Linear[band_pos_fx] = L_shl_sat( L_band_energy_Linear[band_pos_fx], sub( QbeL, exp_pow ) );
2616 0 : move32();
2617 : /* Div Part */
2618 0 : exp_normd = norm_l( L_be_tonal[band_pos_fx] );
2619 0 : exp_normd = sub( exp_normd, 1 );
2620 0 : exp_normn = norm_l( L_band_energy_Linear[band_pos_fx] );
2621 0 : temp_fx = div_l( L_shl( L_be_tonal[band_pos_fx], exp_normd ), extract_h( L_shl( L_band_energy_Linear[band_pos_fx], exp_normn ) ) ); /* QbeL+exp_normd-(QbeL+exp_normn-16)-1 */
2622 0 : sqrt_32n_16_fx( L_deposit_h( temp_fx ), add( sub( exp_normd, exp_normn ), 31 ), &temp_fx, &Qtemp );
2623 0 : enrd_r_fx = extract_h( L_shl_sat( L_mult( enrd_r_fx, temp_fx ), sub( 15, Qtemp ) ) );
2624 0 : enrd_r_fx = sub( enrd_r_fx, step_fx );
2625 : }
2626 : ELSE
2627 : {
2628 0 : enrd_r_fx = 0x0;
2629 0 : move16();
2630 : }
2631 :
2632 0 : IF( EQ_16( p2aflags[band_pos_fx], 1 ) )
2633 : {
2634 0 : FOR( i = band_start[band_pos_fx]; i <= band_end[band_pos_fx]; i++ )
2635 : {
2636 0 : L_outBuf[i - fLenLow] = L_codbuf[i];
2637 0 : move32();
2638 : }
2639 : }
2640 : ELSE
2641 : {
2642 0 : pos_fx = 0;
2643 0 : move16();
2644 0 : pos_fx = add( pos_fx, pos_tmp_fx );
2645 0 : exp_shift = sub( sub( QsL, Qss ), 1 );
2646 0 : FOR( j = 0; j < pul_res_pk[k_fx]; j++ )
2647 : {
2648 : /*outBuf[pk_sf[k*8+j].gainIndex] = pk_sf[k*8+j].nmrValue*band_sf[pos]*enrd_r;*/
2649 : /* outBuf:QsL , pk_sf.nmrValue:Qss, band_sf:Qbsf2(Qton_sf), enrd_r:Q15 */
2650 0 : L_outBuf[pk_sf_fx[k_fx * 8 + j].gainIndex_fx] = L_shl( Mult_32_16( L_mult( band_sf_fx[pos_fx], enrd_r_fx ), pk_sf_fx[k_fx * 8 + j].nmrValue_fx ), sub( exp_shift, Qbsf2[pos_fx] ) );
2651 0 : move32(); /* QsL - (Qbsf2[pos_fx]+Qss+16-15) */
2652 :
2653 0 : pos_fx = add( pos_fx, 1 );
2654 : }
2655 : }
2656 0 : pos_tmp_fx = add( pos_tmp_fx, pul_res_pk[k_fx] );
2657 : }
2658 :
2659 0 : return;
2660 : }
2661 :
2662 :
2663 : /*-------------------------------------------------------------------*
2664 : * sqrt_32n_16_fx()
2665 : *
2666 : * Routine for Sqrt
2667 : *-------------------------------------------------------------------*/
2668 514 : void sqrt_32n_16_fx(
2669 : Word32 L_in, /* i : input vector (Word32) */
2670 : Word16 Qin, /* i : Q value for L_in */
2671 : Word16 *out_fx, /* o : sqrt input vector (Word16) */
2672 : Word16 *Qout /* o : Q value for out_fx */
2673 : )
2674 : {
2675 : Word16 exp_norm;
2676 : Word32 L_in_t;
2677 : Word16 Qin_t;
2678 :
2679 : /* Input Normalization */
2680 514 : exp_norm = norm_l( L_in );
2681 514 : L_in_t = L_shl( L_in, exp_norm );
2682 514 : Qin_t = add( Qin, exp_norm );
2683 :
2684 : /* SQRT part */
2685 514 : IF( s_and( Qin_t, 1 ) == 0 )
2686 : {
2687 223 : L_in_t = Sqrt_l( L_shr( L_in_t, 1 ), &exp_norm );
2688 223 : L_in_t = L_shr( L_in_t, exp_norm );
2689 223 : *Qout = sub( shr( Qin_t, 1 ), 1 );
2690 : }
2691 : ELSE
2692 : {
2693 291 : L_in_t = Sqrt_l( L_in_t, &exp_norm );
2694 291 : L_in_t = L_shr( L_in_t, exp_norm );
2695 291 : *Qout = shr( Qin_t, 1 );
2696 : }
2697 514 : move16();
2698 514 : *out_fx = round_fx( L_in_t );
2699 514 : }
2700 :
2701 : /*-------------------------------------------------------------------*
2702 : * norm_vec_32_16_scale_fx()
2703 : *
2704 : * Routine for normilization and convert Word32 to Word16
2705 : *-------------------------------------------------------------------*/
2706 66 : void norm_vec_32_16_scale_fx(
2707 : Word32 *L_vec_in, /* i : input vector */
2708 : Word16 Qin, /* i : Q value for input vector */
2709 : Word16 length_fx, /* i :vector size */
2710 : Word16 *vec_out_fx, /* o : output vectror */
2711 : Word16 *Qout, /* o : Q value for output vectro */
2712 : Word16 exp_safe /* i : suppress left shift: for prevend overflow on sum */
2713 : )
2714 : {
2715 : Word16 i;
2716 : Word32 L_temp;
2717 : Word16 exp_norm, exp_shift;
2718 :
2719 66 : L_temp = L_deposit_l( 0 );
2720 20658 : FOR( i = 0; i < length_fx; i++ )
2721 : {
2722 20592 : L_temp = L_or( L_temp, L_abs( L_vec_in[i] ) );
2723 : }
2724 66 : exp_norm = norm_l( L_temp );
2725 :
2726 66 : exp_shift = sub( exp_norm, exp_safe );
2727 66 : *Qout = sub( add( Qin, exp_shift ), 16 );
2728 20658 : FOR( i = 0; i < length_fx; i++ )
2729 : {
2730 20592 : vec_out_fx[i] = round_fx( L_shl( L_vec_in[i], exp_shift ) );
2731 20592 : move16();
2732 : }
2733 66 : }
2734 :
2735 144 : void get_sigma_fx_har(
2736 : const Word32 L_x_abs[], /* i: Qi absolute input */
2737 : const Word16 Qi, /* i: Q0 Q value of x_abs */
2738 : const Word16 avg_fx, /* i: Qavg average of x_abs */
2739 : const Word16 Qavg, /* i: Q0 Q value of avg */
2740 : const Word16 length_fx, /* i: Q0 length */
2741 : Word16 *sigma_fx, /* o: Qsigma sigma */
2742 : Word16 *Qsigma /* o: Q0 Q value of sigma */
2743 : )
2744 : {
2745 : Word16 i;
2746 : Word32 L_d;
2747 : Word16 d_fx;
2748 :
2749 : Word16 length1_fx;
2750 : Word16 exp_normd;
2751 : Word16 exp_normn;
2752 : Word16 exp_shift;
2753 :
2754 : Word16 exp_norm;
2755 :
2756 : Word32 L_temp;
2757 :
2758 : Word16 temp_fx;
2759 :
2760 : Word32 L_tmp;
2761 : Word32 L_x_abs_sh[L_FRAME32k];
2762 : Word16 Qd;
2763 :
2764 : Word16 exp_safe;
2765 :
2766 144 : exp_safe = 4;
2767 144 : move16(); /* max 103 < 2^7 -> 4+4=8 */
2768 :
2769 144 : L_tmp = L_deposit_l( 0 );
2770 11376 : FOR( i = 0; i < length_fx; i++ )
2771 : {
2772 11232 : L_tmp = L_or( L_tmp, L_x_abs[i] );
2773 : }
2774 144 : exp_norm = norm_l( L_tmp );
2775 144 : exp_norm = sub( exp_norm, exp_safe );
2776 11376 : FOR( i = 0; i < length_fx; i++ )
2777 : {
2778 11232 : L_x_abs_sh[i] = L_shl( L_x_abs[i], exp_norm );
2779 11232 : move32();
2780 : }
2781 :
2782 144 : L_d = L_deposit_l( 0 );
2783 11376 : FOR( i = 0; i < length_fx; i++ )
2784 : {
2785 11232 : temp_fx = extract_h( L_x_abs_sh[i] );
2786 11232 : L_d = L_mac( L_d, temp_fx, temp_fx ); /* (Qi+exp_norm-16)*2+1 */
2787 : }
2788 144 : Qd = add( shl( sub( add( Qi, exp_norm ), 16 ), 1 ), 1 );
2789 144 : IF( L_d == 0x0L )
2790 : {
2791 0 : *sigma_fx = 0;
2792 0 : move16();
2793 0 : *Qsigma = 15;
2794 0 : move16();
2795 0 : return;
2796 : }
2797 :
2798 : /* d /= (length-1); */
2799 144 : length1_fx = sub( length_fx, 1 );
2800 :
2801 : /* d /= (length-1); */
2802 144 : exp_normn = norm_l( L_d );
2803 144 : exp_normn = sub( exp_normn, 1 );
2804 144 : exp_normd = norm_s( length1_fx );
2805 :
2806 144 : exp_shift = sub( sub( exp_normn, exp_normd ), 1 );
2807 144 : d_fx = div_l( L_shl( L_d, exp_normn ), shl( length1_fx, exp_normd ) ); /* Qabs*2+1+exp_normn - exp_normd - 1 */
2808 144 : L_d = L_shr( L_deposit_l( d_fx ), exp_shift ); /* Qabs*2+1 + 16 */
2809 : /* Qd = ((Qd+exp_normn) - exp_normd-exp_shift -1); */
2810 144 : Qd = sub( sub( add( Qd, exp_normn ), add( exp_normd, exp_shift ) ), 1 );
2811 :
2812 : /* d -= avg*avg; */
2813 144 : IF( avg_fx != 0x0 )
2814 : {
2815 144 : L_tmp = L_mult( avg_fx, avg_fx ); /* Qavg*2+1 */
2816 144 : L_tmp = L_shr( L_tmp, sub( add( shl( Qavg, 1 ), 1 ), Qd ) );
2817 144 : L_d = L_sub( L_d, L_tmp );
2818 : }
2819 :
2820 144 : exp_norm = norm_l( L_d );
2821 144 : L_d = L_shl( L_d, exp_norm );
2822 144 : Qd = add( Qd, exp_norm );
2823 :
2824 : /* sigma = (float)sqrt(d); */
2825 144 : IF( s_and( Qd, 1 ) == 0 ) /* Qd % 2 == 0 */
2826 : {
2827 66 : L_temp = Sqrt_l( L_shr( L_d, 1 ), &exp_norm );
2828 66 : L_temp = L_shr( L_temp, exp_norm );
2829 66 : *Qsigma = sub( shr( Qd, 1 ), 1 );
2830 66 : *sigma_fx = round_fx( L_temp );
2831 : }
2832 : ELSE
2833 : {
2834 78 : L_temp = Sqrt_l( L_d, &exp_norm );
2835 78 : L_temp = L_shr( L_temp, exp_norm );
2836 78 : *Qsigma = shr( Qd, 1 );
2837 78 : *sigma_fx = round_fx( L_temp );
2838 : }
2839 144 : move16();
2840 144 : move16();
2841 144 : return;
2842 : }
2843 :
2844 144 : void FindNBiggest2_simple_fx_har(
2845 : const Word32 *L_inBuf, /* i : input buffer (searched) */
2846 : const Word16 Qabs_in, /* i : Q value of input buffer */
2847 : GainItem_fx *pk_sf_fx, /* o : N biggest components found */
2848 : const Word16 nIdx_fx, /* i : search length */
2849 : Word16 *n_fx, /* i : number of components searched (N biggest) */
2850 : Word16 n_nbiggestsearch /* i : */
2851 : )
2852 : {
2853 : Word16 j;
2854 : Word32 L_avg_in;
2855 : Word32 L_abs_in[400];
2856 : Word32 L_abs_in_sft[400];
2857 : Word16 avg_in_fx;
2858 : Word32 L_max_in;
2859 : Word16 Qavg_in;
2860 :
2861 : Word16 exp_normd;
2862 : Word16 exp_normn;
2863 :
2864 : Word16 temp_fx;
2865 :
2866 : Word16 sigma_fx;
2867 : Word16 Qsigma;
2868 :
2869 : Word16 peak_cnt_fx;
2870 : Word32 L_thr;
2871 : Word32 L_temp;
2872 :
2873 144 : L_max_in = L_deposit_l( 0 );
2874 144 : L_avg_in = L_deposit_l( 0 );
2875 :
2876 11376 : FOR( j = 0; j < nIdx_fx; j++ )
2877 : {
2878 11232 : L_abs_in[j] = L_abs( L_inBuf[j] ); /* Qabs_in */
2879 11232 : L_abs_in_sft[j] = L_shr( L_abs_in[j], 8 ); /* 8 is safe shift */
2880 11232 : move32();
2881 11232 : move32();
2882 11232 : if ( LT_32( L_max_in, L_abs_in_sft[j] ) )
2883 : {
2884 725 : L_max_in = L_abs_in_sft[j];
2885 725 : move32();
2886 : }
2887 :
2888 11232 : L_avg_in = L_add( L_avg_in, L_abs_in_sft[j] );
2889 : }
2890 :
2891 : /*avg_in /= (float)nIdx;*/
2892 144 : avg_in_fx = 0;
2893 144 : move16();
2894 144 : Qavg_in = 15;
2895 144 : move16();
2896 144 : IF( L_avg_in != 0 )
2897 : {
2898 144 : exp_normn = norm_l( L_avg_in );
2899 144 : exp_normn = sub( exp_normn, 1 );
2900 144 : L_avg_in = L_shl( L_avg_in, exp_normn );
2901 144 : exp_normd = norm_s( nIdx_fx );
2902 144 : temp_fx = shl( nIdx_fx, exp_normd );
2903 144 : avg_in_fx = div_l( L_avg_in, temp_fx );
2904 144 : Qavg_in = sub( add( sub( Qabs_in, 8 ), exp_normn ), add( exp_normd, 1 ) );
2905 : }
2906 :
2907 144 : peak_cnt_fx = 0;
2908 144 : move16();
2909 144 : IF( LE_32( L_max_in, 0x1 ) )
2910 : {
2911 0 : FOR( j = 0; j < n_nbiggestsearch; j++ )
2912 : {
2913 0 : pk_sf_fx[peak_cnt_fx].nmrValue_fx = 0x0;
2914 0 : move16();
2915 0 : pk_sf_fx[peak_cnt_fx].gainIndex_fx = j;
2916 0 : move16();
2917 0 : peak_cnt_fx = add( peak_cnt_fx, 1 );
2918 : }
2919 : }
2920 :
2921 144 : get_sigma_fx_har( L_abs_in, Qabs_in, avg_in_fx, Qavg_in, nIdx_fx, &sigma_fx, &Qsigma );
2922 :
2923 144 : temp_fx = mult_r( sigma_fx, 18841 ); /* 18841 = 1.15(Q14) Qsigma + Q14 + 1 */
2924 144 : L_thr = L_add( extract_l( avg_in_fx ), L_shr( extract_l( temp_fx ), sub( sub( Qsigma, 1 ), Qavg_in ) ) );
2925 144 : L_thr = L_shr( L_thr, sub( Qavg_in, Qabs_in ) );
2926 :
2927 144 : IF( LT_16( peak_cnt_fx, n_nbiggestsearch ) )
2928 : {
2929 11376 : FOR( j = 0; j < nIdx_fx; j++ )
2930 : {
2931 11232 : IF( GT_32( L_abs_in[j], L_thr ) )
2932 : {
2933 1366 : pk_sf_fx[peak_cnt_fx].nmrValue_fx = round_fx( L_abs_in[j] ); /* Qabs_in-16 */
2934 1366 : move16();
2935 1366 : pk_sf_fx[peak_cnt_fx].gainIndex_fx = j;
2936 1366 : move16();
2937 1366 : L_abs_in[j] = L_deposit_l( 0 );
2938 1366 : peak_cnt_fx = add( peak_cnt_fx, 1 );
2939 1366 : move16();
2940 : }
2941 :
2942 11232 : IF( EQ_16( peak_cnt_fx, n_nbiggestsearch ) )
2943 : {
2944 0 : BREAK;
2945 : }
2946 : }
2947 : }
2948 :
2949 : /* thr *= (0.3f / n_nbiggestsearch) * peak_cnt + 0.7f; */
2950 : /* 0.3=19661(Q16) */
2951 144 : temp_fx = div_s_ss( 19661, n_nbiggestsearch );
2952 144 : L_temp = L_mult( temp_fx, peak_cnt_fx ); /* 16+0+1 */
2953 144 : temp_fx = add( round_fx( L_shl( L_temp, 14 ) ), 22938 ); /* shift: 17+14-16 -> 15 */ /* 0.7(22937.6:Q15)*/
2954 144 : L_thr = Mult_32_16( L_thr, temp_fx );
2955 :
2956 144 : IF( LT_16( peak_cnt_fx, n_nbiggestsearch ) )
2957 : {
2958 10771 : FOR( j = 0; j < nIdx_fx; j++ )
2959 : {
2960 10645 : IF( GT_32( L_abs_in[j], L_thr ) )
2961 : {
2962 537 : pk_sf_fx[peak_cnt_fx].nmrValue_fx = round_fx( L_abs_in[j] ); /* Qabs_in-16 */
2963 537 : pk_sf_fx[peak_cnt_fx].gainIndex_fx = j;
2964 537 : move16();
2965 537 : L_abs_in[j] = L_deposit_l( 0 );
2966 537 : peak_cnt_fx = add( peak_cnt_fx, 1 );
2967 537 : move16();
2968 : }
2969 :
2970 10645 : IF( EQ_16( peak_cnt_fx, n_nbiggestsearch ) )
2971 : {
2972 18 : BREAK;
2973 : }
2974 : }
2975 : }
2976 :
2977 : /* thr *= (0.6f / n_nbiggestsearch) * peak_cnt + 0.3f; */
2978 : /* 0.6=19661(Q15) */
2979 144 : temp_fx = div_s_ss( 19661, n_nbiggestsearch );
2980 144 : L_temp = L_mult( temp_fx, peak_cnt_fx ); /* 15+0+1 */
2981 144 : temp_fx = add( round_fx( L_shl( L_temp, 15 ) ), 9830 ); /* shift: 16+15-16 -> 15 */ /* 0.3(9830.4:Q15)*/
2982 :
2983 144 : L_thr = Mult_32_16( L_thr, temp_fx );
2984 144 : IF( LT_16( peak_cnt_fx, n_nbiggestsearch ) )
2985 : {
2986 4628 : FOR( j = 0; j < nIdx_fx; j++ )
2987 : {
2988 4620 : IF( GT_32( L_abs_in[j], L_thr ) )
2989 : {
2990 675 : pk_sf_fx[peak_cnt_fx].nmrValue_fx = round_fx( L_abs_in[j] ); /* Qabs_in-16 */
2991 675 : pk_sf_fx[peak_cnt_fx].gainIndex_fx = j;
2992 675 : move16();
2993 675 : L_abs_in[j] = L_deposit_l( 0 );
2994 675 : peak_cnt_fx = add( peak_cnt_fx, 1 );
2995 675 : move16();
2996 : }
2997 :
2998 4620 : IF( EQ_16( peak_cnt_fx, n_nbiggestsearch ) )
2999 : {
3000 118 : BREAK;
3001 : }
3002 : }
3003 : }
3004 :
3005 144 : *n_fx = peak_cnt_fx;
3006 144 : move16();
3007 144 : }
3008 :
3009 : /*--------------------------------------------------------------------------*
3010 : * spectrumsmooth_noiseton()
3011 : * Spectrum normalization for the the core coder
3012 : *--------------------------------------------------------------------------*/
3013 66 : Word16 spectrumsmooth_noiseton_fx( /* o : Qss ss_min */
3014 : Word32 L_spectra[], /* i : Qs core coder */
3015 : /*Word16 Qs,*/ /* i : Q0 Q value for spectra, spectra_ni */
3016 : const Word32 L_spectra_ni[], /* i : Qs core coder with sparse filling */
3017 : Word16 sspectra_fx[], /* o : Qss Smoothed tonal information from core coder */
3018 : Word16 sspectra_diff_fx[], /* o : Qss non tonal infomration for gap filling */
3019 : Word16 sspectra_ni_fx[], /* o : Qss smoothed core coder */
3020 : Word16 *Qss, /* o : Q0 Q value for sspectra* */
3021 : const Word16 fLenLow_fx, /* i : Q0 low frequency boundaries */
3022 : Word16 *ni_seed_fx /* io : Q0 random seed */
3023 : )
3024 : {
3025 : Word16 i;
3026 : Word32 L_spectra_diff[L_FRAME32k];
3027 : Word16 ni_ratio_fx; /* Q15 */
3028 : Word16 ss_min_fx; /* Q10 */
3029 : Word16 cut_sig_th_fx; /* Q10 */
3030 : Word16 cut_ni_th_fx; /* Q10 */
3031 : Word16 pcnt_fx, sign_fx;
3032 : Word16 exp_normn, exp_normd;
3033 :
3034 : Word16 ratio_fx;
3035 : Word32 L_temp;
3036 : Word32 L_spectra_rm[L_FRAME32k];
3037 66 : Word32 L_cut_input = 410;
3038 66 : move32();
3039 : Word16 rand_a_fx[L_FRAME32k];
3040 :
3041 :
3042 : /* pre-prepare random array for float-fix interoperability */
3043 16962 : FOR( i = 0; i < fLenLow_fx; i++ )
3044 : {
3045 16896 : rand_a_fx[i] = Random( ni_seed_fx );
3046 16896 : move16();
3047 : }
3048 :
3049 :
3050 : /*Get the pulse resolution for the core coder*/
3051 66 : pcnt_fx = 0;
3052 66 : move16();
3053 16962 : FOR( i = 0; i < fLenLow_fx; i++ )
3054 : {
3055 16896 : if ( L_spectra[i] != 0x0L )
3056 : {
3057 1869 : pcnt_fx = add( pcnt_fx, 1 );
3058 : }
3059 : }
3060 :
3061 : /*ni_ratio = 4.0f*(pcnt)/(fLenLow+0.0f);*/
3062 66 : exp_normn = norm_s( pcnt_fx );
3063 66 : exp_normn = sub( exp_normn, 1 );
3064 66 : exp_normd = norm_s( fLenLow_fx );
3065 :
3066 66 : ni_ratio_fx = div_s( shl( pcnt_fx, exp_normn ), shl( fLenLow_fx, exp_normd ) ); /* exp_normn - exp_normd + 15 - 2 */
3067 :
3068 66 : ni_ratio_fx = shl( ni_ratio_fx, add( sub( exp_normd, exp_normn ), 2 ) ); /* 15 - (exp_normn-exp_normd+15-2) */
3069 :
3070 : /*ni_ratio = min(0.9f, ni_ratio);*/
3071 66 : ni_ratio_fx = s_min( 29491, ni_ratio_fx ); /* 0.9: 29491(Q15) */
3072 :
3073 66 : move16();
3074 :
3075 66 : ss_min_fx = mult_r( ni_ratio_fx, 10240 ); /* Q15+Q10-15 = Q10 */ /* 10.0: 10240(Q10) */
3076 66 : cut_sig_th_fx = shr( ss_min_fx, 2 ); /* 1/4 */
3077 66 : cut_sig_th_fx = s_max( 973, cut_sig_th_fx ); /* 0.95: 972.8(Q10) */
3078 :
3079 : /*core coder normalization for gap filling*/
3080 16962 : FOR( i = 0; i < fLenLow_fx; i++ )
3081 : {
3082 16896 : L_spectra_rm[i] = L_deposit_l( 0 );
3083 16896 : if ( GE_32( L_abs( L_spectra[i] ), L_cut_input ) )
3084 : {
3085 1869 : L_spectra_rm[i] = L_spectra[i];
3086 1869 : move32();
3087 : }
3088 : }
3089 66 : SpectrumSmoothing_fx( L_spectra_rm, sspectra_fx, Qss, fLenLow_fx, cut_sig_th_fx );
3090 :
3091 : /*Extract noise informaton from the core coder*/
3092 66 : Copy( sspectra_fx, sspectra_ni_fx, fLenLow_fx );
3093 16962 : FOR( i = 0; i < fLenLow_fx; i++ )
3094 : {
3095 16896 : L_spectra_diff[i] = L_sub( L_spectra_ni[i], L_spectra[i] );
3096 16896 : move32();
3097 : }
3098 66 : cut_ni_th_fx = 0x0;
3099 66 : move16();
3100 : /*normalize sparse filled components*/
3101 16962 : FOR( i = 0; i < fLenLow_fx; i++ )
3102 : {
3103 16896 : L_spectra_rm[i] = L_deposit_l( 0 );
3104 16896 : move32();
3105 16896 : if ( GE_32( L_abs( L_spectra_diff[i] ), L_cut_input ) )
3106 : {
3107 12216 : L_spectra_rm[i] = L_spectra_diff[i];
3108 12216 : move32();
3109 : }
3110 : }
3111 66 : SpectrumSmoothing_fx( L_spectra_rm, sspectra_diff_fx, Qss, fLenLow_fx, cut_ni_th_fx );
3112 :
3113 : /*Normalized corecoder for Gap filling */
3114 : /* ratio = 1 - ss_min/10.0 */
3115 66 : ratio_fx = sub( 0x7fff, shl( mult_r( ss_min_fx, 3277 ), 15 - 10 ) ); /* Q15 */
3116 16962 : FOR( i = 0; i < fLenLow_fx; i++ )
3117 : {
3118 16896 : sign_fx = 0;
3119 16896 : move16();
3120 16896 : if ( sspectra_fx[i] < 0 )
3121 : {
3122 1517 : sign_fx = 1;
3123 1517 : move16();
3124 : }
3125 16896 : IF( GT_16( abs_s( sspectra_fx[i] ), ss_min_fx ) )
3126 : {
3127 : /*sspectra[i] = sign*((10-ss_min)/10.0f*(float)fabs(sspectra[i])+ss_min);*/
3128 1885 : sspectra_fx[i] = add( mult_r( ratio_fx, abs_s( sspectra_fx[i] ) ), ss_min_fx );
3129 1885 : move16();
3130 1885 : IF( sign_fx != 0 )
3131 : {
3132 906 : sspectra_fx[i] = negate( sspectra_fx[i] );
3133 906 : move16();
3134 : }
3135 : }
3136 16896 : IF( sspectra_fx[i] != 0x0 )
3137 : {
3138 3158 : sspectra_ni_fx[i] = sspectra_fx[i];
3139 3158 : move16();
3140 : }
3141 : ELSE
3142 : {
3143 13738 : sspectra_ni_fx[i] = mult_r( sspectra_diff_fx[i], ni_ratio_fx );
3144 13738 : move16();
3145 : }
3146 :
3147 16896 : IF( sspectra_ni_fx[i] == 0x0 )
3148 : {
3149 : /*sspectra_ni[i] = 0.5f*10.0f*ni_ratio* own_random(ni_seed)/32768.0f;*/
3150 2524 : L_temp = L_mult( ni_ratio_fx, 20480 ); /* ni_ratio*5 */
3151 2524 : L_temp = Mult_32_16( L_temp, rand_a_fx[i] ); /* Q28 */
3152 2524 : sspectra_ni_fx[i] = round_fx( L_shr( L_temp, 2 ) ); /* Qss */
3153 2524 : move16();
3154 : }
3155 : }
3156 :
3157 66 : return ( ss_min_fx );
3158 : }
3159 :
3160 : /*--------------------------------------------------------------------------*
3161 : * noiseinj_hf()
3162 : * level adjustments for the missing bands in the core coder
3163 : *--------------------------------------------------------------------------*/
3164 66 : void noiseinj_hf_fx(
3165 : Word32 L_xSynth_har[], /* i/o : Qs gap filled information */
3166 : Word16 Qs, /* i : Q0 Q value for xSynth_har */
3167 : Word32 L_th_g[], /* i : Qs level adjustment information */
3168 : Word32 L_band_energy[], /* i : Qbe subband energies */
3169 : Word16 Qbe, /* i : Q0 Q value for band_energy */
3170 : Word16 *prev_En_sb_fx, /* i/o : QsEn smoothed sqrt band Energies */
3171 : const Word16 p2a_flags_fx[], /* i : Q0 Missing bands in the core coder */
3172 : const Word16 BANDS_fx, /* i : Q0 total bands */
3173 : const Word16 band_start_fx[], /* i : Q0 band start indices */
3174 : const Word16 band_end_fx[], /* i : Q0 band end indices */
3175 : const Word16 fLenLow_fx, /* i : Q0 low frequency bandwidth */
3176 : const Word16 fLenHigh_fx /* i : Q0 SWB frequency bandwidth */
3177 : )
3178 : {
3179 : Word16 k, i;
3180 :
3181 : Word16 *p_prev_En_sb_fx;
3182 66 : Word16 QbeL = 7; /* Don't need 3, because this E only use under th samples */ /* QsEn=3 */
3183 66 : move16();
3184 : Word16 map_pulse_t_fx[L_FRAME32k];
3185 : Word16 map_pulse_fx[L_FRAME32k];
3186 :
3187 66 : Word16 QsEn = 4; /* kiken */
3188 66 : move16();
3189 : Word32 L_En[NB_SWB_SUBBANDS];
3190 : Word32 *p_L_En;
3191 : Word16 QE;
3192 : Word16 sqrt_En_fx[NB_SWB_SUBBANDS]; /* QsEn */
3193 : Word16 *p_sqrt_En_fx; /* QsEn */
3194 :
3195 : Word16 Enn_sm_sb_fx[NB_SWB_SUBBANDS];
3196 : Word16 *p_Enn_sm_sb_fx;
3197 :
3198 : Word16 exp_safe;
3199 : Word16 xSynth_har_fx[L_FRAME32k];
3200 : Word16 QxSynth;
3201 :
3202 : Word16 Qtemp;
3203 :
3204 : Word16 ni_scale_fx; /* Q14 */
3205 :
3206 : Word16 temp_fx;
3207 : Word32 L_temp;
3208 :
3209 : Word16 exp_normn, exp_normd;
3210 : Word16 div_fx;
3211 : Word16 Qdiv;
3212 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
3213 66 : Flag Overflow = 0;
3214 66 : move32();
3215 : #endif
3216 66 : set16_fx( map_pulse_t_fx, 0, band_end_fx[BANDS_fx - 1] + 1 );
3217 66 : set16_fx( map_pulse_fx, 0, band_end_fx[BANDS_fx - 1] + 1 );
3218 :
3219 : /*level adjust the missing bands in the core coder */
3220 66 : exp_safe = 4; /*move16();*/
3221 66 : move16();
3222 66 : norm_vec_32_16_scale_fx( L_xSynth_har, Qs, fLenHigh_fx, xSynth_har_fx, &QxSynth, exp_safe );
3223 66 : QE = add( shl( QxSynth, 1 ), 1 );
3224 :
3225 66 : p_L_En = L_En;
3226 66 : move32();
3227 66 : p_sqrt_En_fx = sqrt_En_fx;
3228 330 : FOR( k = sub( BANDS_fx, NB_SWB_SUBBANDS ); k < BANDS_fx; k++ )
3229 : {
3230 264 : *p_L_En = L_deposit_l( 0 );
3231 264 : move32();
3232 264 : IF( p2a_flags_fx[k] == 0 )
3233 : {
3234 20177 : FOR( i = band_start_fx[k]; i <= band_end_fx[k]; i++ ){
3235 19920 : IF( LE_32( L_abs( L_xSynth_har[i - fLenLow_fx] ), L_th_g[k - ( BANDS_fx - NB_SWB_SUBBANDS )] ) ){
3236 17217 : *p_L_En = L_mac( *p_L_En, xSynth_har_fx[i - fLenLow_fx], xSynth_har_fx[i - fLenLow_fx] );
3237 17217 : move32();
3238 : }
3239 : ELSE
3240 : {
3241 2703 : map_pulse_t_fx[i] = 1;
3242 2703 : move16();
3243 : }
3244 : }
3245 257 : *p_L_En = L_shl_sat( *p_L_En, sub( QbeL, QE ) );
3246 257 : move32();
3247 : /**p_L_En = (float)sqrt(*p_En);*/
3248 257 : sqrt_32n_16_fx( *p_L_En, QbeL, p_sqrt_En_fx, &Qtemp );
3249 257 : *p_sqrt_En_fx = shl_o( *p_sqrt_En_fx, sub( QsEn, Qtemp ), &Overflow ); /* -> Q2 */
3250 257 : move16();
3251 : }
3252 264 : p_L_En++;
3253 264 : p_sqrt_En_fx++;
3254 : }
3255 :
3256 66 : p_sqrt_En_fx = sqrt_En_fx;
3257 66 : p_Enn_sm_sb_fx = Enn_sm_sb_fx;
3258 66 : p_prev_En_sb_fx = prev_En_sb_fx;
3259 330 : FOR( k = BANDS_fx - NB_SWB_SUBBANDS; k < BANDS_fx; k++ )
3260 : {
3261 264 : *p_Enn_sm_sb_fx = prev_En_sb_fx[k - ( BANDS_fx - NB_SWB_SUBBANDS )];
3262 264 : move16(); /* QsEn */
3263 264 : IF( p2a_flags_fx[k] == 0 )
3264 : {
3265 257 : L_temp = Mult_32_16( L_band_energy[k], 26214 ); /* 0.8: 26214(Q15) */
3266 257 : temp_fx = round_fx( L_shl( L_temp, sub( QsEn, sub( Qbe, 16 ) ) ) );
3267 257 : IF( LT_16( *p_prev_En_sb_fx, temp_fx ) )
3268 : {
3269 : /**p_Enn_sm_sb = (0.15f*(*p_En)) + (0.85f*prev_En_sb[k-(BANDS-NB_SWB_SUBBANDS)]);*/
3270 : /* 0.15: 4915.2(Q15) 0.85: 27852.80(Q15) */
3271 31 : *p_Enn_sm_sb_fx = round_fx( L_mac( L_mult( *p_sqrt_En_fx, 4915 ), *p_prev_En_sb_fx, 27853 ) );
3272 : }
3273 : ELSE
3274 : {
3275 : /**p_Enn_sm_sb = (0.8f*(*p_En)) + (0.2f*prev_En_sb[k-(BANDS-NB_SWB_SUBBANDS)]);*/
3276 : /* 0.8: 26214.4(Q15) 0.2:6553.6(Q15) */
3277 226 : *p_Enn_sm_sb_fx = round_fx( L_mac( L_mult( *p_sqrt_En_fx, 26214 ), *p_prev_En_sb_fx, 6554 ) );
3278 : }
3279 257 : move16();
3280 : }
3281 :
3282 264 : p_Enn_sm_sb_fx++;
3283 264 : p_sqrt_En_fx++;
3284 264 : p_prev_En_sb_fx++;
3285 : }
3286 :
3287 66 : p_sqrt_En_fx = sqrt_En_fx;
3288 66 : p_Enn_sm_sb_fx = Enn_sm_sb_fx;
3289 66 : p_prev_En_sb_fx = prev_En_sb_fx;
3290 66 : map_pulse_fx[fLenLow_fx] = ( map_pulse_t_fx[fLenLow_fx] | map_pulse_t_fx[fLenLow_fx + 1] );
3291 66 : logic16();
3292 66 : move16();
3293 20526 : FOR( i = fLenLow_fx + 1; i < band_end_fx[BANDS_fx - 1]; i++ )
3294 : {
3295 20460 : map_pulse_fx[i] = ( map_pulse_t_fx[i - 1] | map_pulse_t_fx[i] | map_pulse_t_fx[i + 1] );
3296 20460 : logic16();
3297 20460 : logic16();
3298 20460 : move16();
3299 : }
3300 66 : map_pulse_fx[i] = ( map_pulse_t_fx[i - 1] | map_pulse_t_fx[i] );
3301 66 : logic16();
3302 66 : move16();
3303 :
3304 330 : FOR( k = BANDS_fx - NB_SWB_SUBBANDS; k < BANDS_fx; k++ )
3305 : {
3306 264 : test();
3307 264 : IF( p2a_flags_fx[k] == 0 && *p_sqrt_En_fx != 0x0 )
3308 : {
3309 : /*ni_scale = sqrt((*p_Enn_sm_sb)/(*p_En));*/
3310 : /* Div Part */
3311 257 : exp_normn = norm_s( *p_Enn_sm_sb_fx );
3312 257 : exp_normn = sub( exp_normn, 1 );
3313 257 : exp_normd = norm_s( *p_sqrt_En_fx );
3314 257 : div_fx = div_s( shl( *p_Enn_sm_sb_fx, exp_normn ), shl( *p_sqrt_En_fx, exp_normd ) );
3315 257 : Qdiv = add( sub( exp_normn, exp_normd ), 15 );
3316 :
3317 : /* SQRT Part */
3318 257 : sqrt_32n_16_fx( L_deposit_h( div_fx ), add( Qdiv, 16 ), &ni_scale_fx, &Qtemp );
3319 257 : ni_scale_fx = shl_o( ni_scale_fx, sub( 14, Qtemp ), &Overflow );
3320 257 : ni_scale_fx = s_min( 20408, ni_scale_fx ); /* 1.25=20408.0(Q14) */
3321 :
3322 257 : ni_scale_fx = s_max( 12288, ni_scale_fx ); /* 0.75=12288.0(Q14) */
3323 :
3324 257 : ni_scale_fx = mult_r( ni_scale_fx, 26214 ); /* 0.8=26214.4(Q15) -> Q14 */
3325 20177 : FOR( i = band_start_fx[k]; i <= band_end_fx[k]; i++ ){
3326 19920 : IF( LE_32( L_abs( L_xSynth_har[i - fLenLow_fx] ), L_th_g[k - ( BANDS_fx - NB_SWB_SUBBANDS )] ) ){
3327 17217 : IF( map_pulse_fx[i] == 0 ){
3328 13393 : L_xSynth_har[i - fLenLow_fx] = L_shl( Mult_32_16( L_xSynth_har[i - fLenLow_fx], ni_scale_fx ), 1 ); /* Q12+Q14-15-1 = Q12 */
3329 13393 : move32();
3330 : }
3331 : }
3332 : }
3333 257 : *p_prev_En_sb_fx = *p_Enn_sm_sb_fx;
3334 257 : move16();
3335 : }
3336 264 : p_Enn_sm_sb_fx++;
3337 264 : p_sqrt_En_fx++;
3338 264 : p_prev_En_sb_fx++;
3339 : }
3340 :
3341 66 : return;
3342 : }
3343 :
3344 : /*--------------------------------------------------------------------------*
3345 : * updat_prev_frm()
3346 : *
3347 : *
3348 : *--------------------------------------------------------------------------*/
3349 69 : void updat_prev_frm_fx(
3350 : Word32 L_y2[], /* i/o: core coder buffer */
3351 : Word32 L_t_audio[], /* o: core coder buffer */
3352 : Word32 L_bwe_br, /* i: core bitrate */
3353 : Word16 length_fx, /* i: frame length coded bw */
3354 : const Word16 inner_frame_fx, /* i: input frame length */
3355 : Word16 bands_fx, /* i: sub band resolution */
3356 : Word16 bwidth_fx, /* i: NB/WB/SWB indicator */
3357 : const Word16 is_transient_fx, /* i: signal class information */
3358 : Word16 hqswb_clas_fx, /* i: signal class information */
3359 : Word16 *prev_hqswb_clas, /* o: update signal class information */
3360 : Word16 prev_SWB_peak_pos_fx[], /* o: update core coder last coded peaks*/
3361 : Word16 prev_SWB_peak_pos_tmp_fx[], /* o: update core coder last coded peaks*/
3362 : Word16 *prev_frm_hfe2, /* o: update harmonics */
3363 : Word16 *prev_stab_hfe2, /* o: update harmonics */
3364 : Word16 bws_cnt_fx /* i: band width detector */
3365 : )
3366 : {
3367 : Word16 i, j, k;
3368 : Word16 k1_fx, k2_fx;
3369 : Word16 length1_fx, length2_fx, length3_fx;
3370 :
3371 : /* Copy the coded MDCT coefficient to the output buffer */
3372 69 : IF( !is_transient_fx )
3373 : {
3374 : /* Copy the scratch buffer to the output */
3375 66 : Copy32( L_y2, L_t_audio, length_fx );
3376 :
3377 : /* If the input frame is larger than coded bandwidth, zero out uncoded MDCT coefficients */
3378 66 : IF( GT_16( inner_frame_fx, length_fx ) )
3379 : {
3380 66 : set32_fx( L_t_audio + length_fx, 0x0L, sub( inner_frame_fx, length_fx ) );
3381 : }
3382 : }
3383 : ELSE /* transient frame */
3384 : {
3385 3 : test();
3386 3 : IF( EQ_16( inner_frame_fx, length_fx ) || bws_cnt_fx > 0 )
3387 : {
3388 : /* Copy the scratch buffer to the output */
3389 0 : Copy32( L_y2, L_t_audio, length_fx );
3390 : }
3391 : ELSE
3392 : {
3393 : /* length/NUM_TIME_SWITCHING_BLOCKS */
3394 : /*length1_fx = div_s_ss(length_fx, NUM_TIME_SWITCHING_BLOCKS); */
3395 3 : length1_fx = shr( length_fx, 2 ); /* length1 = length/NUM_TIME_SWITCHING_BLOCKS */
3396 : /* inner_frame/NUM_TIME_SWITCHING_BLOCKS */
3397 : /*length2_fx = div_s_ss(inner_frame_fx, NUM_TIME_SWITCHING_BLOCKS); */
3398 3 : length2_fx = shr( inner_frame_fx, 2 ); /* length2 = inner_frame/NUM_TIME_SWITCHING_BLOCKS */
3399 : /* (inner_frame-length)/NUM_TIME_SWITCHING_BLOCKS */
3400 : /*length3_fx = div_s_ss(sub(inner_frame_fx, length_fx), NUM_TIME_SWITCHING_BLOCKS); */
3401 3 : length3_fx = shr( sub( inner_frame_fx, length_fx ), 2 ); /* (inner_frame-length)/NUM_TIME_SWITCHING_BLOCKS */
3402 :
3403 3 : k1_fx = 0;
3404 3 : move16();
3405 3 : k2_fx = 0;
3406 3 : move16();
3407 :
3408 : /* un-collapse transient frame and interleave zeros */
3409 15 : FOR( i = 0; i < NUM_TIME_SWITCHING_BLOCKS; i++ )
3410 : {
3411 : /*k1 = i*length/NUM_TIME_SWITCHING_BLOCKS; */
3412 : /*k2 = i*inner_frame/NUM_TIME_SWITCHING_BLOCKS; */
3413 :
3414 12 : Copy32( L_y2 + k1_fx, L_t_audio + k2_fx, length1_fx );
3415 12 : set32_fx( L_t_audio + k2_fx + length1_fx, 0x0L, length3_fx );
3416 :
3417 12 : k1_fx = add( k1_fx, length1_fx );
3418 12 : k2_fx = add( k2_fx, length2_fx );
3419 : }
3420 : }
3421 : }
3422 :
3423 69 : test();
3424 69 : test();
3425 69 : IF( ( EQ_32( L_bwe_br, HQ_16k40 ) || EQ_32( L_bwe_br, HQ_13k20 ) ) && EQ_16( bwidth_fx, SWB ) )
3426 : {
3427 69 : *prev_hqswb_clas = hqswb_clas_fx;
3428 69 : move16();
3429 69 : IF( NE_16( hqswb_clas_fx, HQ_HARMONIC ) )
3430 : {
3431 69 : *prev_frm_hfe2 = 0;
3432 69 : move16();
3433 69 : *prev_stab_hfe2 = 0;
3434 69 : move16();
3435 : }
3436 : }
3437 : ELSE
3438 : {
3439 0 : *prev_hqswb_clas = is_transient_fx;
3440 0 : move16();
3441 : }
3442 :
3443 69 : test();
3444 69 : test();
3445 69 : test();
3446 69 : IF( ( EQ_32( L_bwe_br, HQ_16k40 ) || EQ_32( L_bwe_br, HQ_13k20 ) ) && EQ_16( bwidth_fx, SWB ) && EQ_16( hqswb_clas_fx, HQ_NORMAL ) )
3447 : {
3448 66 : j = 0;
3449 66 : move16();
3450 330 : FOR( k = sub( bands_fx, SPT_SHORTEN_SBNUM ); k < bands_fx; k++ )
3451 : {
3452 264 : prev_SWB_peak_pos_fx[j] = prev_SWB_peak_pos_tmp_fx[j];
3453 264 : move16();
3454 264 : j = add( j, 1 );
3455 : }
3456 : }
3457 :
3458 69 : return;
3459 : }
|