Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 : #include <stdint.h>
5 : #include "options.h" /* Compilation switches */
6 : #include "cnst.h" /* Common constants */
7 : //#include "prot_fx.h" /* Function prototypes */
8 : #include "rom_com_fx.h" /* Static table prototypes */
9 : #include "rom_com.h" /* Static table prototypes */
10 : #include "prot_fx.h" /* Function prototypes */
11 : #include "prot_fx_enc.h" /* Function prototypes */
12 :
13 : /*-----------------------------------------------------------------*
14 : * Local constants
15 : *-----------------------------------------------------------------*/
16 :
17 : #define SHARP_DIST_THRES_FX 1420 /* Q6, 22.2 */
18 :
19 : #define HALF_WIN_LENGTH 10
20 : #define L_SPEC_HB 320
21 : #define PEAK_THRESHOLD 3277 /*Q15 0.1f*/
22 : #define PEAK_THRESHOLD_FX 214748364 // 0.1f in Q31
23 : #define LOW_COUNT_THRESHOLD 220
24 :
25 :
26 : /*-----------------------------------------------------------------*
27 : * Local functions
28 : *-----------------------------------------------------------------*/
29 :
30 : void hvq_classifier_fx( const Word32 *input /*Q12*/, Word16 *prev_Npeaks, Word16 *prev_peaks, Word16 *hqswb_clas, Word16 *Npeaks, Word16 *peaks, const Word32 L_core_brate, const Word16 last_core, Word32 *L_nf_gains /*Q12*/, Word16 *hvq_hangover, Word32 *L_pe_gains /*Q12*/ );
31 : static Word16 hf_spectrum_sparseness_fx(
32 : Encoder_State *st, /* i/o: encoder state structure */
33 : const Word32 *coefs_fx /* i : MDCT spectrum Q12*/
34 : );
35 : /*--------------------------------------------------------------------------*
36 : * hf_spectrum_sparseness()
37 : *
38 : * Detection of sparse spectrum in high band for activation of harmonic
39 : * modes HQ_HARMONIC and HQ_HVQ
40 : *--------------------------------------------------------------------------*/
41 : /*! r: Harmonic decision for high band */
42 6696 : static Word16 hf_spectrum_sparseness_fx(
43 : Encoder_State *st, /* i/o: encoder state structure */
44 : const Word32 *coefs_fx /* i : MDCT spectrum (Q12) */
45 : )
46 : {
47 : Word16 i;
48 : Word32 thr_fx;
49 : Word16 low_count_fx;
50 : Word32 Amax_fx;
51 : Word32 movmean_fx;
52 : Word64 inv_rms_fx;
53 : Word32 inv_rms32_fx;
54 : Word32 inv_rms32_div_fx;
55 : Word32 crest_fx;
56 : Word32 crest_mod_fx;
57 : const Word16 *p_num_fx;
58 : Word32 A_fx[960];
59 : Word16 result;
60 : Word32 *crest_lp_fx;
61 : Word32 *crest_mod_lp_fx;
62 : Word32 hq_crest_threshold, hq_crest_mod_threshold;
63 6696 : Word16 inv_rms32_e = 0;
64 6696 : move16();
65 :
66 6696 : crest_lp_fx = &st->hHQ_core->crest_lp_fx; /* &st->hHQ_core->crest_lp_q */
67 6696 : crest_mod_lp_fx = &st->hHQ_core->crest_mod_lp_fx; /* &st->hHQ_core->crest_mod_lp_q */
68 :
69 6696 : result = TRUE;
70 6696 : move16();
71 6696 : IF( st->element_mode != EVS_MONO )
72 : {
73 :
74 2149416 : FOR( i = 0; i < L_SPEC_HB; i++ )
75 : {
76 2142720 : A_fx[i] = L_abs( coefs_fx[i + L_SPEC_HB] ); /* Q12 */
77 2142720 : move32();
78 : }
79 6696 : low_count_fx = 0;
80 6696 : move16();
81 6696 : inv_rms_fx = 0;
82 6696 : move64();
83 6696 : crest_mod_fx = 0;
84 6696 : move32();
85 6696 : maximum_l( A_fx, L_SPEC_HB, &Amax_fx );
86 6696 : IF( Amax_fx == 0 )
87 : {
88 : /* For all-zero input the crest is 1.0 */
89 0 : crest_fx = L_shl( 1, st->hHQ_core->crest_lp_q ); /* &st->hHQ_core->crest_lp_q */
90 0 : crest_mod_fx = L_shl( 1, st->hHQ_core->crest_mod_lp_q ); /* &st->hHQ_core->crest_mod_lp_q */
91 0 : low_count_fx = 0;
92 0 : move16();
93 : }
94 : ELSE
95 : {
96 6696 : thr_fx = Mpy_32_32( Amax_fx, PEAK_THRESHOLD_FX ); /* Q12 */
97 6696 : movmean_fx = 0; /* avoid uninitialized warning */
98 6696 : move32();
99 : // p_num = &inv_tbl[HALF_WIN_LENGTH + 1]; /* Table for division 1./(11:21) */
100 6696 : p_num_fx = &inv_tbl_fx[HALF_WIN_LENGTH + 1]; /* Table for division 1./(11:21) Q15*/
101 2149416 : FOR( i = 0; i < L_SPEC_HB; i++ )
102 : {
103 : // inv_rms += A[i] * A[i];
104 2142720 : inv_rms_fx = W_add( inv_rms_fx, W_shr( W_mult0_32_32( A_fx[i], A_fx[i] ), Q9 ) ); // 2*Q12 -Q9 (Q9 for guard bits) Q15
105 :
106 2142720 : IF( LT_32( A_fx[i], thr_fx ) )
107 : {
108 1361061 : low_count_fx = add( low_count_fx, 1 );
109 : }
110 2142720 : IF( LE_16( i, HALF_WIN_LENGTH ) )
111 : {
112 73656 : IF( i == 0 )
113 : {
114 6696 : movmean_fx = Mpy_32_16_1( sum_l_fx( &A_fx[0], i + HALF_WIN_LENGTH + 1 ), ( *p_num_fx ) ); // Q12
115 : }
116 : ELSE
117 : {
118 :
119 66960 : p_num_fx++;
120 66960 : movmean_fx = L_add( movmean_fx, Mpy_32_16_1( L_sub( A_fx[i + HALF_WIN_LENGTH], movmean_fx ), ( *p_num_fx ) ) ); // Q12
121 : }
122 : }
123 : ELSE
124 : {
125 2069064 : IF( LE_16( L_SPEC_HB, i + HALF_WIN_LENGTH ) )
126 : {
127 :
128 66960 : p_num_fx--;
129 66960 : movmean_fx = L_add( movmean_fx, Mpy_32_16_1( L_sub( movmean_fx, A_fx[i - HALF_WIN_LENGTH - 1] ), ( *p_num_fx ) ) ); // Q12
130 : }
131 : ELSE
132 : {
133 2002104 : movmean_fx = L_add( movmean_fx, Mpy_32_16_1( L_sub( A_fx[i + HALF_WIN_LENGTH], A_fx[i - HALF_WIN_LENGTH - 1] ), ( *p_num_fx ) ) ); // Q12
134 : }
135 : }
136 :
137 2142720 : IF( LT_32( crest_mod_fx, movmean_fx ) )
138 : {
139 89145 : crest_mod_fx = movmean_fx; // Q12
140 89145 : move32();
141 : }
142 : }
143 6696 : Word16 l_shift = W_norm( inv_rms_fx );
144 6696 : inv_rms32_fx = W_extract_h( W_shl( inv_rms_fx, l_shift ) ); // Q15+l_shift-32
145 6696 : Word16 q_rms = sub( add( Q15, l_shift ), 32 ); // q_rms
146 6696 : inv_rms32_div_fx = BASOP_Util_Divide3232_Scale_newton( inv_rms32_fx, L_SPEC_HB, &inv_rms32_e ); /* Q31-inv_rms32_e */
147 6696 : inv_rms32_e = sub( 31, add( sub( Q31, inv_rms32_e ), q_rms ) );
148 : // inv_rms = 1.0f / (float) sqrtf( inv_rms / L_SPEC_HB );
149 6696 : inv_rms32_fx = ISqrt32( inv_rms32_div_fx, &inv_rms32_e ); /* Q31-inv_rms32_e */
150 :
151 6696 : crest_fx = Mpy_32_32( Amax_fx, inv_rms32_fx ); // Q12 + (Q31-inv_rms32_e) -Q31 = Q12 - inv_rms32_e
152 6696 : crest_mod_fx = Mpy_32_32( crest_mod_fx, inv_rms32_fx ); // Q12 + (Q31-inv_rms32_e) -Q31 = Q12 - inv_rms32_e
153 6696 : *crest_lp_fx = L_shr( *crest_lp_fx, sub( st->hHQ_core->crest_lp_q, sub( Q12, inv_rms32_e ) ) ); /* Q12-inv_rms32_e */
154 6696 : move32();
155 6696 : st->hHQ_core->crest_lp_q = sub( Q12, inv_rms32_e );
156 6696 : move16();
157 6696 : *crest_mod_lp_fx = L_shr( *crest_mod_lp_fx, sub( st->hHQ_core->crest_mod_lp_q, sub( Q12, inv_rms32_e ) ) ); /* Q12-inv_rms32_e */
158 6696 : move32();
159 6696 : st->hHQ_core->crest_mod_lp_q = sub( Q12, inv_rms32_e );
160 6696 : move16();
161 : }
162 6696 : *crest_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, ( *crest_lp_fx ) ), Mpy_32_32( ONE_IN_Q31 - HQ_CREST_FAC_SM_FX, crest_fx ) ); /* Q(st->hHQ_core->crest_lp_q) */
163 6696 : move32();
164 6696 : *crest_mod_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, ( *crest_mod_lp_fx ) ), Mpy_32_32( L_sub( ONE_IN_Q31, HQ_CREST_FAC_SM_FX ), crest_mod_fx ) ); /* Q(st->hHQ_core->crest_mod_lp_q) */
165 6696 : move32();
166 :
167 6696 : hq_crest_threshold = L_shr( HQ_CREST_THRESHOLD_FX, sub( Q28, st->hHQ_core->crest_lp_q ) ); /* Q(st->hHQ_core->crest_lp_q) */
168 6696 : hq_crest_mod_threshold = L_shr( HQ_CREST_MOD_THRESHOLD_FX, sub( Q29, st->hHQ_core->crest_mod_lp_q ) ); /* Q(st->hHQ_core->crest_mod_lp_q) */
169 6696 : test();
170 6696 : test();
171 6696 : if ( GT_32( ( *crest_lp_fx ), hq_crest_threshold ) && GT_32( ( *crest_mod_lp_fx ), hq_crest_mod_threshold ) && GT_16( low_count_fx, LOW_COUNT_THRESHOLD ) )
172 : {
173 14 : result = FALSE;
174 14 : move16();
175 : }
176 : }
177 :
178 6696 : return result; /* Q0 */
179 : }
180 : /*--------------------------------------------------------------------------*
181 : * hq_classifier_enc_fx()
182 : *
183 : * HQ mode selector (decision_matrix)
184 : *--------------------------------------------------------------------------*/
185 392 : Word16 hq_classifier_enc_fx( /* o : Consumed bits Q0 */
186 : Encoder_State *st_fx, /* i/o: encoder state structure */
187 : const Word16 length, /* i : Frame length Q0 */
188 : const Word32 *coefs, /* i : Spectral coefficients Q12 */
189 : const Word16 is_transient, /* i : Transient flag Q0 */
190 : Word16 *Npeaks, /* o : Number of identified peaks Q0 */
191 : Word16 *peaks, /* o : Peak indices Q0 */
192 : Word32 *pe_gains, /* o : Peak gains Q12 */
193 : Word32 *nf_gains, /* o : Noise-fill gains Q12 */
194 : Word16 *hqswb_clas /* o : HQ class Q0 */
195 : )
196 : {
197 : Word16 bits;
198 392 : HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core;
199 :
200 392 : *hqswb_clas = HQ_NORMAL;
201 392 : IF( EQ_16( is_transient, 1 ) )
202 : {
203 35 : *hqswb_clas = HQ_TRANSIENT;
204 35 : move16();
205 : }
206 :
207 : /* classification and limit bandwidth for bit allocation */
208 392 : test();
209 392 : test();
210 392 : test();
211 392 : IF( EQ_16( length, L_FRAME32k ) && NE_16( is_transient, 1 ) && LE_32( st_fx->core_brate, HQ_32k ) && EQ_16( st_fx->bwidth, st_fx->last_bwidth ) )
212 : {
213 : /* Detect HQ_HARMONIC mode */
214 66 : *hqswb_clas = peak_avrg_ratio_fx( st_fx->total_brate, coefs, NUMC_N + 96, &hHQ_core->mode_count, &hHQ_core->mode_count1, 12 ); /* Q0 */
215 66 : move16();
216 :
217 : /* Detect harmonic VQ mode HQ_HVQ */
218 66 : hvq_classifier_fx( coefs, &hHQ_core->prev_Npeaks, hHQ_core->prev_peaks, hqswb_clas, Npeaks, peaks, st_fx->core_brate, st_fx->last_core,
219 : nf_gains, &hHQ_core->hvq_hangover, pe_gains );
220 : }
221 :
222 392 : test();
223 392 : test();
224 392 : test();
225 392 : IF( EQ_16( length, L_FRAME48k ) && NE_16( is_transient, 1 ) && LE_32( st_fx->core_brate, HQ_32k ) && EQ_16( st_fx->bwidth, st_fx->last_bwidth ) )
226 : {
227 : /* Detect HQ_HARMONIC mode */
228 0 : *hqswb_clas = peak_avrg_ratio_fx( st_fx->total_brate, coefs, NUMC_N + 96, &hHQ_core->mode_count, &hHQ_core->mode_count1, 12 ); /* Q0 */
229 0 : move16();
230 : /* Detect harmonic VQ mode HQ_HVQ */
231 0 : hvq_classifier_fx( coefs, &hHQ_core->prev_Npeaks, hHQ_core->prev_peaks, hqswb_clas, Npeaks, peaks,
232 0 : st_fx->core_brate, st_fx->last_core, nf_gains, &hHQ_core->hvq_hangover, pe_gains );
233 : }
234 :
235 392 : test();
236 392 : test();
237 392 : IF( EQ_16( length, L_FRAME48k ) && LE_32( st_fx->core_brate, HQ_32k ) && EQ_16( *hqswb_clas, HQ_NORMAL ) )
238 : {
239 0 : *hqswb_clas = HQ_GEN_FB; /* Q0 */
240 0 : move16();
241 : }
242 :
243 392 : test();
244 392 : IF( GE_16( length, L_FRAME32k ) && LE_32( st_fx->core_brate, HQ_32k ) )
245 : {
246 66 : bits = 2;
247 66 : move16();
248 : }
249 : ELSE
250 : {
251 326 : bits = 1;
252 326 : move16();
253 : }
254 :
255 392 : test();
256 392 : IF( EQ_16( length, L_FRAME48k ) && LE_32( st_fx->core_brate, HQ_32k ) )
257 : {
258 0 : IF( GE_16( *hqswb_clas, HQ_GEN_SWB ) )
259 : {
260 0 : push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas - 5, bits );
261 : }
262 : ELSE
263 : {
264 0 : push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits );
265 : }
266 : }
267 : ELSE
268 : {
269 392 : push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits );
270 : }
271 :
272 392 : test();
273 392 : test();
274 392 : IF( EQ_16( *hqswb_clas, HQ_NORMAL ) && EQ_16( length, L_FRAME32k ) && LE_32( st_fx->core_brate, HQ_32k ) )
275 : {
276 46 : *hqswb_clas = HQ_GEN_SWB; /* Q0 */
277 46 : move16();
278 : }
279 :
280 392 : return bits;
281 : }
282 7801 : Word16 hq_classifier_enc_ivas_fx( /* o : Consumed bits Q0 */
283 : Encoder_State *st_fx, /* i/o: encoder state structure */
284 : const Word16 length, /* i : Frame length Q0 */
285 : const Word32 *coefs, /* i : Spectral coefficients Q12 */
286 : const Word16 is_transient, /* i : Transient flag Q0 */
287 : Word16 *Npeaks, /* o : Number of identified peaks Q0 */
288 : Word16 *peaks, /* o : Peak indices Q0 */
289 : Word32 *pe_gains, /* o : Peak gains Q12 */
290 : Word32 *nf_gains, /* o : Noise-fill gains Q12 */
291 : Word16 *hqswb_clas /* o : HQ class Q0 */
292 : )
293 : {
294 :
295 :
296 : Word16 bits;
297 7801 : HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core;
298 : Word32 max_brate;
299 : Word16 harmonic_decision;
300 :
301 :
302 7801 : max_brate = HQ_32k;
303 7801 : move32();
304 :
305 7801 : if ( st_fx->element_mode > EVS_MONO )
306 : {
307 7801 : max_brate = HQ_48k;
308 7801 : move32();
309 : }
310 :
311 7801 : *hqswb_clas = HQ_NORMAL; /* Q0 */
312 7801 : bits = 1;
313 7801 : move16();
314 7801 : IF( EQ_16( is_transient, 1 ) )
315 : {
316 460 : *hqswb_clas = HQ_TRANSIENT; /* Q0 */
317 460 : move16();
318 : }
319 :
320 : /* classification and limit bandwidth for bit allocation */
321 7801 : test();
322 7801 : IF( EQ_16( length, L_SPEC32k ) || EQ_16( length, L_SPEC48k ) )
323 : {
324 7156 : IF( LE_32( st_fx->core_brate, max_brate ) )
325 : {
326 7156 : test();
327 7156 : IF( !is_transient && EQ_16( st_fx->bwidth, st_fx->last_bwidth ) )
328 : {
329 : /* Detect HQ_HARMONIC mode */
330 6696 : *hqswb_clas = peak_avrg_ratio_ivas_fx( st_fx->total_brate, coefs, NUMC_N + 96, &hHQ_core->mode_count, &hHQ_core->mode_count1, 12 ); /* Q0 */
331 :
332 6696 : harmonic_decision = hf_spectrum_sparseness_fx( st_fx, coefs );
333 :
334 :
335 6696 : test();
336 6696 : IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && !harmonic_decision )
337 : {
338 0 : *hqswb_clas = HQ_NORMAL; /* Q0 */
339 0 : move16();
340 : }
341 : ELSE
342 : {
343 : /* Detect harmonic VQ mode HQ_HVQ */
344 6696 : hvq_classifier_ivas_fx( coefs, &hHQ_core->prev_Npeaks, hHQ_core->prev_peaks, hqswb_clas, Npeaks, peaks, st_fx->core_brate, st_fx->last_core, nf_gains, &hHQ_core->hvq_hangover, pe_gains );
345 : }
346 : }
347 7156 : bits = 2;
348 7156 : move16();
349 : }
350 : }
351 645 : ELSE IF( EQ_16( length, L_SPEC16k_EXT ) || EQ_16( length, L_SPEC48k_EXT ) )
352 : {
353 145 : bits = 0; /* HQ_NORMAL only -- no signalling needed */
354 145 : move16();
355 : }
356 : /* write signalling info to the bitstream */
357 7801 : push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits );
358 :
359 7801 : IF( LE_32( st_fx->core_brate, HQ_32k ) && EQ_16( *hqswb_clas, HQ_NORMAL ) )
360 : {
361 3285 : IF( EQ_16( length, L_SPEC32k ) )
362 : {
363 605 : *hqswb_clas = HQ_GEN_SWB; /* Q0 */
364 605 : move16();
365 : }
366 2680 : ELSE IF( EQ_16( length, L_SPEC48k ) )
367 : {
368 2210 : *hqswb_clas = HQ_GEN_FB; /* Q0 */
369 2210 : move16();
370 : }
371 : }
372 :
373 7801 : return bits; /* Q0 */
374 : }
375 : /*--------------------------------------------------------------------------*
376 : * peak_avrg_ratio()
377 : *
378 : * Classify the input signal and decide if it has a harmonic structure
379 : *--------------------------------------------------------------------------*/
380 6696 : Word16 peak_avrg_ratio_ivas_fx(
381 : const Word32 total_brate, /* i : total bitrate Q0*/
382 : const Word32 *input_hi_fx, /* i : input signal Q_coeff */
383 : const Word16 length, /* i : number of coefficients Q0*/
384 : Word16 *mode_count, /* i/o: HQ_HARMONIC mode count Q0*/
385 : Word16 *mode_count1, /* i/o: HQ_NORMAL mode count Q0*/
386 : Word16 Q_coeff )
387 : {
388 : Word16 i, j, q, k, k1, hqswb_clas;
389 : Word32 mean_fx, peak_fx;
390 : Word32 input_abs_fx[L_FRAME32k];
391 : Word32 peak_th_fx;
392 :
393 3649320 : FOR( i = 96; i < length; i++ )
394 : {
395 3642624 : input_abs_fx[i] = L_abs( input_hi_fx[i] );
396 3642624 : move32();
397 : }
398 :
399 6696 : hqswb_clas = HQ_NORMAL;
400 6696 : move16();
401 6696 : peak_th_fx = L_shl( 10L, sub( Q_coeff, 5 ) ); /* 5 is safe shift */
402 :
403 6696 : k = 0;
404 6696 : move16();
405 6696 : k1 = 0;
406 6696 : move16();
407 6696 : q = 96; /* q used for indexing */
408 6696 : move16();
409 :
410 100440 : FOR( i = 3; i < 17; i++ )
411 : {
412 93744 : peak_fx = L_deposit_l( 0 );
413 93744 : mean_fx = L_deposit_l( 1 );
414 :
415 : /*for(j = 0; j < 32; j ++, q ++) */
416 3093552 : FOR( j = 0; j < 32; j++ )
417 : {
418 2999808 : input_abs_fx[q] = L_shr( input_abs_fx[q], 5 ); /*Q_coeff-5 */
419 2999808 : move32();
420 2999808 : mean_fx = L_add( mean_fx, input_abs_fx[q] ); /*Q_coeff-5 */
421 2999808 : if ( GT_32( input_abs_fx[q], peak_fx ) )
422 : {
423 414179 : peak_fx = input_abs_fx[q]; /*Q_coeff-5 */
424 414179 : move32();
425 : }
426 2999808 : q += 1;
427 : }
428 :
429 93744 : IF( LT_16( i, 8 ) )
430 : {
431 33480 : if ( GT_32( peak_fx, Mult_32_16( mean_fx, 4608 ) ) ) /* Q15 0.140625 */
432 : {
433 22413 : k = add( k, 1 );
434 : }
435 : }
436 : ELSE
437 : {
438 60264 : test();
439 60264 : if ( GT_32( peak_fx, Mult_32_16( mean_fx, 3686 ) ) /*Q15 0.1125 */
440 25829 : && GT_32( peak_fx, peak_th_fx ) ) /*Q27 10 */
441 : {
442 22366 : k1 = add( k1, 1 );
443 : }
444 : }
445 : }
446 :
447 6696 : test();
448 6696 : IF( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) )
449 : {
450 1699 : IF( LT_16( *mode_count, 8 ) )
451 : {
452 1699 : *mode_count = add( *mode_count, 1 );
453 1699 : move16();
454 : }
455 :
456 1699 : IF( *mode_count1 > 0 )
457 : {
458 0 : *mode_count1 = sub( *mode_count1, 1 );
459 0 : move16();
460 : }
461 : }
462 : ELSE
463 : {
464 4997 : IF( LT_16( *mode_count1, 8 ) )
465 : {
466 4997 : *mode_count1 = add( *mode_count1, 1 );
467 4997 : move16();
468 : }
469 :
470 4997 : IF( *mode_count > 0 )
471 : {
472 0 : *mode_count = sub( *mode_count, 1 );
473 0 : move16();
474 : }
475 : }
476 :
477 6696 : test();
478 6696 : test();
479 6696 : test();
480 6696 : test();
481 6696 : test();
482 6696 : test();
483 :
484 6696 : IF( ( GE_16( add( k, k1 ), 5 ) && GT_16( k1, 2 ) && LT_32( total_brate, HQ_BWE_CROSSOVER_BRATE ) ) || ( ( ( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) ) || GE_16( *mode_count, 5 ) ) && LT_16( *mode_count1, 5 ) ) )
485 : {
486 2258 : hqswb_clas = HQ_HARMONIC;
487 2258 : move16();
488 : }
489 6696 : return hqswb_clas; /* Q0 */
490 : }
491 : /*--------------------------------------------------------------------------*
492 : * peak_avrg_ratio()
493 : *
494 : * Classify the input signal and decide if it has a harmonic structure
495 : *--------------------------------------------------------------------------*/
496 104 : Word16 peak_avrg_ratio_fx(
497 : const Word32 total_brate, /* i : total bitrate Q0*/
498 : const Word32 *input_hi_fx, /* i : input signal Q_coeff*/
499 : const Word16 length, /* i : number of coefficients Q0*/
500 : Word16 *mode_count, /* i/o: HQ_HARMONIC mode count Q0*/
501 : Word16 *mode_count1, /* i/o: HQ_NORMAL mode count Q0*/
502 : Word16 Q_coeff )
503 : {
504 : Word16 i, j, q, k, k1, hqswb_clas;
505 : Word32 mean_fx, peak_fx;
506 : Word32 input_abs_fx[L_FRAME32k];
507 : Word32 peak_th_fx;
508 :
509 53032 : FOR( i = 96; i < length; i++ )
510 : {
511 52928 : input_abs_fx[i] = L_abs( input_hi_fx[i] ); /* Q_coeff */
512 : }
513 :
514 104 : hqswb_clas = HQ_NORMAL;
515 104 : move16();
516 104 : peak_th_fx = L_shl( 10L, sub( Q_coeff, 5 ) ); /* 5 is safe shift */
517 :
518 104 : k = 0;
519 104 : move16();
520 104 : k1 = 0;
521 104 : move16();
522 104 : q = 96; /* q used for indexing */
523 104 : move16();
524 :
525 1560 : FOR( i = 3; i < 17; i++ )
526 : {
527 1456 : peak_fx = L_deposit_l( 0 );
528 1456 : mean_fx = L_deposit_l( 1 );
529 :
530 : /*for(j = 0; j < 32; j ++, q ++) */
531 48048 : FOR( j = 0; j < 32; j++ )
532 : {
533 46592 : input_abs_fx[q] = L_shr( input_abs_fx[q], 5 ); /*Q_coeff-5 */
534 46592 : move32();
535 46592 : mean_fx = L_add( mean_fx, input_abs_fx[q] ); /*Q_coeff-5 */
536 46592 : if ( GT_32( input_abs_fx[q], peak_fx ) )
537 : {
538 6130 : peak_fx = input_abs_fx[q]; /*Q_coeff-5 */
539 6130 : move32();
540 : }
541 46592 : q += 1;
542 : }
543 :
544 1456 : IF( LT_16( i, 8 ) )
545 : {
546 520 : if ( GT_32( peak_fx, Mult_32_16( mean_fx, 4608 ) ) ) /* Q15 0.140625 */
547 : {
548 96 : k = add( k, 1 );
549 : }
550 : }
551 : ELSE
552 : {
553 936 : test();
554 936 : if ( GT_32( peak_fx, Mult_32_16( mean_fx, 3686 ) ) /*Q15 0.1125 */
555 234 : && GT_32( peak_fx, peak_th_fx ) ) /*Q27 10 */
556 : {
557 216 : k1 = add( k1, 1 );
558 : }
559 : }
560 : }
561 :
562 104 : test();
563 104 : IF( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) )
564 : {
565 0 : IF( LT_16( *mode_count, 8 ) )
566 : {
567 0 : *mode_count = add( *mode_count, 1 );
568 0 : move16();
569 : }
570 :
571 0 : IF( *mode_count1 > 0 )
572 : {
573 0 : *mode_count1 = sub( *mode_count1, 1 );
574 0 : move16();
575 : }
576 : }
577 : ELSE
578 : {
579 104 : IF( LT_16( *mode_count1, 8 ) )
580 : {
581 91 : *mode_count1 = add( *mode_count1, 1 );
582 91 : move16();
583 : }
584 :
585 104 : IF( *mode_count > 0 )
586 : {
587 0 : *mode_count = sub( *mode_count, 1 );
588 0 : move16();
589 : }
590 : }
591 :
592 104 : test();
593 104 : test();
594 104 : test();
595 104 : test();
596 104 : test();
597 104 : test();
598 :
599 104 : IF( ( GE_16( add( k, k1 ), 5 ) && GT_16( k1, 2 ) && EQ_32( total_brate, HQ_24k40 ) ) || ( ( ( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) ) || GE_16( *mode_count, 5 ) ) && LT_16( *mode_count1, 5 ) ) )
600 : {
601 20 : hqswb_clas = HQ_HARMONIC;
602 20 : move16();
603 : }
604 :
605 104 : return hqswb_clas; /* Q0 */
606 : }
607 :
608 : /*--------------------------------------------------------------------------*
609 : * hvq_classifier()
610 : *
611 : * Classification of harmonic low band content for Harmonic VQ
612 : *--------------------------------------------------------------------------*/
613 6696 : void hvq_classifier_ivas_fx(
614 : const Word32 *input, /* i : input signal Q12 */
615 : Word16 *prev_Npeaks, /* i/o: Peak number memory Q0 */
616 : Word16 *prev_peaks, /* i/o: Peak indices memory Q0 */
617 : Word16 *hqswb_clas, /* i/o: HQ class Q0 */
618 : Word16 *Npeaks, /* o : Number of peaks Q0 */
619 : Word16 *peaks, /* o : Peak indices Q0 */
620 : const Word32 L_core_brate, /* i : Core bit-rate Q0 */
621 : const Word16 last_core, /* i : Last core used Q0 */
622 : Word32 *L_nf_gains, /* o : Noisefloor gains Q12 */
623 : Word16 *hvq_hangover, /* i/o: Mode-switch hangover Q0 */
624 : Word32 *L_pe_gains /* o : peak gains Q12 */
625 : )
626 : {
627 : const Word16 *p_adj;
628 : UWord16 lsb;
629 :
630 : Word32 L_input_abs[L_FRAME32k];
631 : Word32 L_input_max;
632 : Word32 L_thr[L_FRAME16k];
633 : Word32 L_thr_tmp;
634 : Word32 L_m;
635 : Word32 L_tmp;
636 : Word32 L_d;
637 : Word32 L_peak;
638 : Word32 L_nf, L_pe;
639 : Word32 L_pe_mean[HVQ_NSUB_32k], L_nf_mean[HVQ_NSUB_32k];
640 :
641 : Word16 inv_nsub;
642 : Word16 sharp_dist;
643 : Word16 exp1, exp2;
644 : Word16 tmp;
645 : Word16 shift;
646 : Word16 idx;
647 : Word16 frac;
648 : Word16 inv_nf_mean;
649 : Word16 inv_gains_nsub;
650 : Word16 nf_mean_norm;
651 : Word16 num_sharp_bands, i, j, k, q, peak_th, nsub, pindx, N, offset;
652 : Word16 num_peak_cands, high, low;
653 : Word16 sharp[HVQ_NSUB_32k];
654 : Word16 peak_cand_idx[HVQ_THRES_BIN_32k], avail_peaks[HVQ_NSUB_32k];
655 : #ifndef ISSUE_1867_replace_overflow_libenc
656 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
657 : Flag Overflow = 0;
658 : move16();
659 : #endif
660 : #endif
661 6696 : Word16 temp_e = 0;
662 6696 : move16();
663 6696 : L_input_max = L_deposit_l( 0 );
664 6696 : set32_fx( L_thr, 0, L_FRAME16k );
665 :
666 6696 : IF( LT_32( L_core_brate, HQ_BWE_CROSSOVER_BRATE ) )
667 : {
668 2654 : nsub = HVQ_NSUB_24k;
669 2654 : move16();
670 2654 : inv_nsub = 4681; /* 1/7 in Q15 */
671 2654 : move16();
672 2654 : inv_gains_nsub = 10923; /* 1/3 in Q15 */
673 2654 : move16();
674 : }
675 : ELSE
676 : {
677 4042 : nsub = HVQ_NSUB_32k;
678 4042 : move16();
679 4042 : inv_nsub = 3277; /* 1/10 in Q15 */
680 4042 : move16();
681 4042 : inv_gains_nsub = 6554; /* 1/5 in Q15 */
682 4042 : move16();
683 : }
684 :
685 6696 : N = shl( nsub, 5 ); /* Mult by 32 (HVQ_BW) */
686 :
687 6696 : test();
688 6696 : test();
689 6696 : IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && last_core != ACELP_CORE && NE_16( last_core, AMR_WB_CORE ) )
690 2228 : {
691 597300 : FOR( i = 0; i < N; i++ )
692 : {
693 595072 : L_input_abs[i] = L_abs( input[i] ); /* Q12 */
694 595072 : move16();
695 595072 : IF( GT_32( L_input_abs[i], L_input_max ) )
696 : {
697 13556 : L_input_max = L_input_abs[i]; /* Q12 */
698 13556 : move16();
699 : }
700 : }
701 :
702 2228 : exp1 = norm_l( L_input_max );
703 :
704 2228 : *Npeaks = 0;
705 2228 : move16();
706 2228 : L_nf = 3276800; /* 800 in Q12 */
707 2228 : move32();
708 2228 : L_pe = 3276800; /* 800 in Q12 */
709 2228 : move32();
710 2228 : num_sharp_bands = 0;
711 2228 : move16();
712 2228 : k = 0;
713 2228 : move16();
714 2228 : q = 0;
715 2228 : move16();
716 2228 : sharp_dist = 0;
717 2228 : move16();
718 :
719 : /* Find peak threshold */
720 20824 : FOR( i = 0; i < nsub; i++ )
721 : {
722 18596 : L_peak = 0;
723 18596 : L_nf_mean[i] = 0;
724 18596 : L_pe_mean[i] = 0;
725 18596 : move32();
726 18596 : move32();
727 18596 : move32();
728 :
729 613668 : FOR( j = 0; j < HVQ_BW; j++ )
730 : {
731 595072 : L_d = L_input_abs[q]; /* Q12 */
732 595072 : IF( GT_32( L_d, L_nf ) )
733 : {
734 : /*nf = HVQ_NF_WEIGHT1 * nf + (1 - HVQ_NF_WEIGHT1) * d; */
735 317930 : Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT1B, &L_tmp, &lsb ); /* 12+15-15=12 */
736 317930 : Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT1_FX, &L_nf, &lsb ); /* 12+15-15=12 */
737 317930 : L_nf = L_add( L_nf, L_tmp ); /*Q12 */
738 : }
739 : ELSE
740 : {
741 : /*nf = HVQ_NF_WEIGHT2 * nf + (1 - HVQ_NF_WEIGHT2) * d; */
742 277142 : Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT2B, &L_tmp, &lsb ); /* 12+15-15=12 */
743 277142 : Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT2_FX, &L_nf, &lsb ); /* 12+15-15=12 */
744 277142 : L_nf = L_add( L_nf, L_tmp ); /*Q12 */
745 : }
746 :
747 595072 : IF( GT_32( L_d, L_pe ) )
748 : {
749 : /*pe = HVQ_PE_WEIGHT1 * pe + (1 - HVQ_PE_WEIGHT1) * d; */
750 118938 : Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT1B, &L_tmp, &lsb ); /* 12+15-15=12 */
751 118938 : Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT1_FX, &L_pe, &lsb ); /* 12+15-15=12 */
752 118938 : L_pe = L_add( L_pe, L_tmp ); /*Q12 */
753 : }
754 : ELSE
755 : {
756 : /*pe = HVQ_PE_WEIGHT2 * pe + (1 - HVQ_PE_WEIGHT2) * d; */
757 476134 : Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT2B, &L_tmp, &lsb ); /* 12+15-15=12 */
758 476134 : Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT2_FX, &L_pe, &lsb ); /* 12+15-15=12 */
759 476134 : L_pe = L_add( L_pe, L_tmp ); /*Q12 */
760 : }
761 :
762 595072 : L_nf_mean[i] = L_add_sat( L_nf_mean[i], L_nf ); /*Q12 */
763 595072 : L_pe_mean[i] = L_add_sat( L_pe_mean[i], L_pe ); /*Q12 */
764 595072 : move32();
765 595072 : move32();
766 595072 : IF( GT_32( L_d, L_peak ) )
767 : {
768 89235 : L_peak = L_add( L_d, 0 );
769 : }
770 :
771 595072 : q += 1;
772 : }
773 18596 : L_nf_mean[i] = L_shr( L_nf_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
774 18596 : L_pe_mean[i] = L_shr( L_pe_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
775 18596 : move32();
776 18596 : move32();
777 : /*thr_tmp = (float)pow( pe_mean[i]/nf_mean[i], HVQ_THR_POW ) * nf_mean[i]; */
778 18596 : exp1 = norm_l( L_nf_mean[i] );
779 18596 : nf_mean_norm = extract_h( L_shl( L_nf_mean[i], exp1 ) ); /* 12+s-16=s-4 */
780 18596 : IF( nf_mean_norm == 0 )
781 : {
782 0 : inv_nf_mean = 0;
783 : }
784 : ELSE
785 : {
786 18596 : inv_nf_mean = div_s( 1 << 14, nf_mean_norm ); /* 15+14-s+4=33-s */
787 : }
788 18596 : Mpy_32_16_ss( L_pe_mean[i], inv_nf_mean, &L_tmp, &lsb ); /*12+33-s-15=30-s */
789 :
790 18596 : exp2 = norm_l( L_tmp );
791 18596 : tmp = Log2_norm_lc( L_shl( L_tmp, exp2 ) ); /* Q15 */
792 18596 : exp2 = sub( exp1, exp2 ); /* Q0 */
793 18596 : L_tmp = Mpy_32_16( exp2, tmp, 32767 ); /* 1 in Q15. Q16 */
794 18596 : Mpy_32_16_ss( L_tmp, 28836, &L_tmp, &lsb ); /* 16+15-15=16 */
795 18596 : frac = L_Extract_lc( L_tmp, &tmp ); /* Q15 and Q0 */
796 18596 : L_tmp = Pow2( 14, frac ); /* Q14 */
797 18596 : L_tmp = L_shl( L_tmp, tmp ); /* Q14 */
798 :
799 18596 : Mpy_32_16_ss( L_tmp, nf_mean_norm, &L_tmp, &lsb ); /*14+s-4-15=s-5 */
800 18596 : shift = sub( 17, exp1 ); /* 16-(s-5)=17-s */
801 18596 : L_thr_tmp = L_shl( L_tmp, shift ); /* Q16 */
802 18596 : L_thr_tmp = L_add( L_thr_tmp, lshr( lsb, sub( 16, shift ) ) ); /*Q16 */
803 :
804 18596 : set32_fx( &L_thr[k], L_thr_tmp, HVQ_BW );
805 18596 : k = add( k, HVQ_BW );
806 :
807 : /*sharp[i] = peak/nf_mean[i]; */
808 18596 : Mpy_32_16_ss( L_peak, inv_nf_mean, &L_tmp, &lsb ); /* 12+33-s-15=30-s */
809 18596 : shift = sub( exp1, 8 );
810 18596 : sharp[i] = extract_h( L_shl( L_tmp, shift ) ); /* 30-s+s-8-16 -> Q6 */
811 18596 : move16();
812 : /*sharp_dist += (sharp[i]-HVQ_SHARP_THRES); */
813 : #ifdef ISSUE_1867_replace_overflow_libenc
814 18596 : sharp_dist = add_sat( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ) ); /* Q6 */
815 : #else
816 : sharp_dist = add_o( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ), &Overflow ); /* Q6 */
817 : #endif
818 18596 : if ( GT_16( sharp[i], HVQ_SHARP_THRES_FX ) )
819 : {
820 16013 : num_sharp_bands = add( num_sharp_bands, 1 );
821 : }
822 : }
823 :
824 : /* Estimate noise floor gains */
825 2228 : offset = s_and( nsub, 1 );
826 19596 : FOR( i = 0; i < ( nsub & (Word16) 0xFFFE ); i++ )
827 : {
828 : /*(2*i+1)/nsub */
829 17368 : idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */
830 17368 : L_nf_gains[idx] = L_add( L_nf_gains[idx], L_nf_mean[i + offset] ); /* Q12 */
831 17368 : L_pe_gains[idx] = L_add( L_pe_gains[idx], L_pe_mean[i + offset] ); /* Q12 */
832 17368 : move32();
833 17368 : move32();
834 : }
835 :
836 6684 : FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
837 : {
838 4456 : Mpy_32_16_ss( L_nf_gains[i], inv_gains_nsub, &L_nf_gains[i], &lsb ); /*12+15-15=12 */
839 4456 : Mpy_32_16_ss( L_pe_gains[i], inv_gains_nsub, &L_pe_gains[i], &lsb ); /*12+15-15=12 */
840 : }
841 :
842 : /* Allocate available peaks */
843 20824 : FOR( i = 0; i < nsub; i++ )
844 : {
845 18596 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP1; /* Q0 */
846 18596 : move16();
847 18596 : idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */
848 18596 : Mpy_32_16_ss( L_nf_gains[idx], HVQ_PA_FAC_FX, &L_tmp, &lsb ); /* 12+15-15 -> Q12 */
849 18596 : IF( LT_32( L_nf_mean[i], L_tmp ) )
850 : {
851 6684 : IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES3_FX ) )
852 : {
853 1487 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP3; /* Q0 */
854 1487 : move16();
855 : }
856 5197 : ELSE IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES2_FX ) )
857 : {
858 673 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP2; /* Q0 */
859 673 : move16();
860 : }
861 : }
862 : }
863 :
864 :
865 : /* Adjust threshold around previous peaks */
866 27058 : FOR( i = 0; i < *prev_Npeaks; i++ )
867 : {
868 24830 : j = sub( prev_peaks[i], 2 ); /* Q0 */
869 24830 : k = add( prev_peaks[i], 2 ); /* Q0 */
870 24830 : p_adj = hvq_thr_adj_fx; /* Q15 */
871 :
872 124150 : FOR( q = j; q < k; q++ )
873 : {
874 99320 : Mpy_32_16_ss( L_thr[q], *p_adj++, &L_thr[q], &lsb ); /* 12+15-15=12 */
875 99320 : move32();
876 : }
877 : }
878 :
879 2228 : num_peak_cands = 0;
880 2228 : move16();
881 :
882 : /* Remove everything below threshold for peak search */
883 2228 : L_input_abs[0] = L_deposit_l( 0 );
884 2228 : L_input_abs[1] = L_deposit_l( 0 );
885 2228 : L_input_abs[N - 2] = L_deposit_l( 0 );
886 2228 : L_input_abs[N - 1] = L_deposit_l( 0 );
887 2228 : move32();
888 2228 : move32();
889 2228 : move32();
890 2228 : move32();
891 592844 : FOR( i = 0; i < N - 2; i++ )
892 : {
893 590616 : IF( LT_32( L_input_abs[i], L_thr[i] ) )
894 : {
895 481953 : L_input_abs[i] = L_deposit_l( 0 );
896 :
897 481953 : move32();
898 : }
899 : ELSE
900 : {
901 108663 : L_input_abs[num_peak_cands] = L_input_abs[i]; /* Q12 */
902 108663 : move32();
903 108663 : peak_cand_idx[num_peak_cands] = i; /* Q0 */
904 108663 : move16();
905 108663 : num_peak_cands = add( num_peak_cands, 1 );
906 : }
907 : }
908 :
909 :
910 2228 : peak_th = extract_l( BASOP_Util_Divide3232_Scale( L_add( W_extract_l( W_mult0_32_32( L_core_brate, HVQ_PEAKS_PER_DELTA_THR ) ), HVQ_PEAKS_PER_DELTA_THR_OFFS ), HVQ_PEAKS_BPS_DELTA, &temp_e ) );
911 2228 : peak_th = shr( peak_th, sub( 15, temp_e ) );
912 : /* Find peaks */
913 2228 : pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
914 2228 : i = 0;
915 2228 : move16();
916 :
917 46676 : WHILE( L_m > 0 && LT_16( i, peak_th + 1 ) )
918 : {
919 44448 : idx = mult( peak_cand_idx[pindx], INV_HVQ_BW ); /* 0+15-15=0 */
920 44448 : IF( avail_peaks[idx] > 0 )
921 : {
922 43425 : peaks[i++] = peak_cand_idx[pindx]; /* Q0 */
923 43425 : avail_peaks[idx]--;
924 : }
925 :
926 44448 : j = sub( pindx, 2 );
927 44448 : k = add( pindx, 2 );
928 :
929 44448 : if ( j < 0 )
930 : {
931 2165 : j = 0;
932 2165 : move16();
933 : }
934 :
935 44448 : tmp = sub( num_peak_cands, 1 );
936 44448 : if ( GT_16( k, tmp ) )
937 : {
938 1559 : k = tmp;
939 1559 : move16();
940 : }
941 :
942 44448 : low = sub( peak_cand_idx[pindx], 2 );
943 44448 : high = add( peak_cand_idx[pindx], 2 );
944 :
945 44448 : if ( low < 0 )
946 : {
947 0 : low = 0;
948 0 : move16();
949 : }
950 :
951 44448 : tmp = sub( N, 1 );
952 44448 : if ( GT_16( high, tmp ) )
953 : {
954 0 : high = tmp;
955 0 : move16();
956 : }
957 :
958 174331 : FOR( q = j; q <= pindx; q++ )
959 : {
960 129883 : IF( GE_16( peak_cand_idx[q], low ) )
961 : {
962 73442 : peak_cand_idx[q] = 0;
963 73442 : move16();
964 73442 : L_input_abs[q] = 0;
965 73442 : move16();
966 : }
967 : }
968 :
969 130973 : FOR( q = pindx + 1; q <= k; q++ )
970 : {
971 86525 : IF( LE_16( peak_cand_idx[q], high ) )
972 : {
973 59481 : peak_cand_idx[q] = 0;
974 59481 : move16();
975 59481 : L_input_abs[q] = 0;
976 59481 : move16();
977 : }
978 : }
979 :
980 44448 : pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
981 : }
982 :
983 2228 : *Npeaks = i; /* Q0 */
984 2228 : move16();
985 2228 : IF( GT_16( *Npeaks, HVQ_MIN_PEAKS ) )
986 : {
987 2228 : test();
988 2228 : IF( GT_16( num_sharp_bands, sub( nsub, 3 ) ) && LE_16( *Npeaks, peak_th ) )
989 : {
990 1231 : sharp_dist = mult( sharp_dist, inv_nsub ); /*x+15-15=x */
991 1231 : test();
992 1231 : IF( LE_16( sharp_dist, SHARP_DIST_THRES_FX ) && *hvq_hangover < 0 )
993 : {
994 39 : *hvq_hangover = add( *hvq_hangover, 1 ); /* Q0 */
995 : }
996 : ELSE
997 : {
998 1192 : *hqswb_clas = HQ_HVQ; /* Q0 */
999 1192 : move16();
1000 1192 : *hvq_hangover = 2; /* Q0 */
1001 1192 : move16();
1002 : }
1003 :
1004 : /* update memory */
1005 1231 : *prev_Npeaks = *Npeaks; /* Q0 */
1006 1231 : move16();
1007 1231 : Copy( peaks, prev_peaks, *Npeaks ); /* Q0 */
1008 : }
1009 : ELSE
1010 : {
1011 997 : IF( *hvq_hangover > 0 )
1012 : {
1013 275 : *hqswb_clas = HQ_HVQ; /* Q0 */
1014 275 : move16();
1015 275 : *hvq_hangover = sub( *hvq_hangover, 1 ); /* Q0 */
1016 275 : move16();
1017 : }
1018 : ELSE
1019 : {
1020 722 : *hvq_hangover = -1;
1021 722 : move16();
1022 : }
1023 : }
1024 : }
1025 : ELSE
1026 : {
1027 : /* Zero peaks, likely silence input. */
1028 0 : *hvq_hangover = -1;
1029 0 : move16();
1030 : }
1031 :
1032 : //*Npeaks = (int16_t) ( s_min( ( L_core_brate * HVQ_PEAKS_PER_DELTA + HVQ_PEAKS_PER_DELTA_OFFS ) / HVQ_PEAKS_BPS_DELTA, *Npeaks ) );
1033 2228 : temp_e = 0;
1034 2228 : move16();
1035 2228 : Word16 Npeaks_temp = *Npeaks;
1036 2228 : *Npeaks = BASOP_Util_Divide3232_Scale( L_add( W_extract_l( W_mult0_32_32( L_core_brate, HVQ_PEAKS_PER_DELTA ) ), HVQ_PEAKS_PER_DELTA_OFFS ), HVQ_PEAKS_BPS_DELTA, &temp_e );
1037 2228 : *Npeaks = s_min( shr( *Npeaks, sub( 15, temp_e ) ), Npeaks_temp );
1038 2228 : move16();
1039 : }
1040 : ELSE
1041 : {
1042 4468 : *prev_Npeaks = 0;
1043 4468 : move16();
1044 4468 : *hvq_hangover = 0;
1045 4468 : move16();
1046 : }
1047 :
1048 :
1049 6696 : return;
1050 : }
1051 :
1052 66 : void hvq_classifier_fx(
1053 : const Word32 *input, /* i : input signal Q12 */
1054 : Word16 *prev_Npeaks, /* i/o: Peak number memory Q0 */
1055 : Word16 *prev_peaks, /* i/o: Peak indices memory Q0 */
1056 : Word16 *hqswb_clas, /* i/o: HQ class Q0 */
1057 : Word16 *Npeaks, /* o : Number of peaks Q0 */
1058 : Word16 *peaks, /* o : Peak indices Q0 */
1059 : const Word32 L_core_brate, /* i : Core bit-rate Q0 */
1060 : const Word16 last_core, /* i : Last core used Q0 */
1061 : Word32 *L_nf_gains, /* o : Noisefloor gains Q12 */
1062 : Word16 *hvq_hangover, /* i/o: Mode-switch hangover Q0 */
1063 : Word32 *L_pe_gains /* o : peak gains Q12 */
1064 : )
1065 : {
1066 : const Word16 *p_adj;
1067 : UWord16 lsb;
1068 :
1069 : Word32 L_input_abs[L_FRAME32k];
1070 : Word32 L_input_max;
1071 : Word32 L_thr[L_FRAME16k];
1072 : Word32 L_thr_tmp;
1073 : Word32 L_m;
1074 : Word32 L_tmp;
1075 : Word32 L_d;
1076 : Word32 L_peak;
1077 : Word32 L_nf, L_pe;
1078 : Word32 L_pe_mean[HVQ_NSUB_32k], L_nf_mean[HVQ_NSUB_32k];
1079 :
1080 : Word16 inv_nsub;
1081 : Word16 sharp_dist;
1082 : Word16 exp1, exp2;
1083 : Word16 tmp;
1084 : Word16 shift;
1085 : Word16 idx;
1086 : Word16 frac;
1087 : Word16 inv_nf_mean;
1088 : Word16 inv_gains_nsub;
1089 : Word16 nf_mean_norm;
1090 : Word16 num_sharp_bands, i, j, k, q, peak_th, nsub, pindx, N, offset;
1091 : Word16 num_peak_cands, high, low;
1092 : Word16 sharp[HVQ_NSUB_32k];
1093 : Word16 peak_cand_idx[HVQ_THRES_BIN_32k], avail_peaks[HVQ_NSUB_32k];
1094 : #ifndef ISSUE_1867_replace_overflow_libenc
1095 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1096 : Flag Overflow = 0;
1097 : move32();
1098 : #endif
1099 : #endif
1100 66 : L_input_max = L_deposit_l( 0 );
1101 66 : set32_fx( L_thr, 0, L_FRAME16k );
1102 :
1103 66 : IF( EQ_32( L_core_brate, HQ_24k40 ) )
1104 : {
1105 66 : nsub = HVQ_NSUB_24k;
1106 66 : move16();
1107 66 : inv_nsub = 4681; /* 1/7 in Q15 */
1108 66 : move16();
1109 66 : inv_gains_nsub = 10923; /* 1/3 in Q15 */
1110 66 : move16();
1111 : }
1112 : ELSE
1113 : {
1114 0 : nsub = HVQ_NSUB_32k;
1115 0 : move16();
1116 0 : inv_nsub = 3277; /* 1/10 in Q15 */
1117 0 : move16();
1118 0 : inv_gains_nsub = 6554; /* 1/5 in Q15 */
1119 0 : move16();
1120 : }
1121 :
1122 66 : N = shl( nsub, 5 ); /* Mult by 32 (HVQ_BW) */
1123 :
1124 66 : test();
1125 66 : test();
1126 66 : IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && last_core != ACELP_CORE && NE_16( last_core, AMR_WB_CORE ) )
1127 : {
1128 4275 : FOR( i = 0; i < N; i++ )
1129 : {
1130 4256 : L_input_abs[i] = L_abs( input[i] ); /* Q12 */
1131 4256 : IF( GT_32( L_input_abs[i], L_input_max ) )
1132 : {
1133 104 : L_input_max = L_input_abs[i]; /* Q12 */
1134 104 : move16();
1135 : }
1136 : }
1137 :
1138 19 : exp1 = norm_l( L_input_max );
1139 :
1140 19 : *Npeaks = 0;
1141 19 : move16();
1142 19 : L_nf = 3276800; /* 800 in Q12 */
1143 19 : move32();
1144 19 : L_pe = 3276800; /* 800 in Q12 */
1145 19 : move32();
1146 19 : num_sharp_bands = 0;
1147 19 : move16();
1148 19 : k = 0;
1149 19 : move16();
1150 19 : q = 0;
1151 19 : move16();
1152 19 : sharp_dist = 0;
1153 19 : move16();
1154 :
1155 : /* Find peak threshold */
1156 152 : FOR( i = 0; i < nsub; i++ )
1157 : {
1158 133 : L_peak = 0;
1159 133 : L_nf_mean[i] = 0;
1160 133 : L_pe_mean[i] = 0;
1161 133 : move32();
1162 133 : move32();
1163 133 : move32();
1164 4389 : FOR( j = 0; j < HVQ_BW; j++ )
1165 : {
1166 4256 : L_d = L_input_abs[q]; /* Q12 */
1167 4256 : move32();
1168 4256 : IF( GT_32( L_d, L_nf ) )
1169 : {
1170 : /*nf = HVQ_NF_WEIGHT1 * nf + (1 - HVQ_NF_WEIGHT1) * d; */
1171 2763 : Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT1B, &L_tmp, &lsb ); /* 12+15-15=12 */
1172 2763 : Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT1_FX, &L_nf, &lsb ); /* 12+15-15=12 */
1173 2763 : L_nf = L_add( L_nf, L_tmp ); /*Q12 */
1174 : }
1175 : ELSE
1176 : {
1177 : /*nf = HVQ_NF_WEIGHT2 * nf + (1 - HVQ_NF_WEIGHT2) * d; */
1178 1493 : Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT2B, &L_tmp, &lsb ); /* 12+15-15=12 */
1179 1493 : Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT2_FX, &L_nf, &lsb ); /* 12+15-15=12 */
1180 1493 : L_nf = L_add( L_nf, L_tmp ); /*Q12 */
1181 : }
1182 :
1183 4256 : IF( GT_32( L_d, L_pe ) )
1184 : {
1185 : /*pe = HVQ_PE_WEIGHT1 * pe + (1 - HVQ_PE_WEIGHT1) * d; */
1186 1110 : Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT1B, &L_tmp, &lsb ); /* 12+15-15=12 */
1187 1110 : Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT1_FX, &L_pe, &lsb ); /* 12+15-15=12 */
1188 1110 : L_pe = L_add( L_pe, L_tmp ); /*Q12 */
1189 : }
1190 : ELSE
1191 : {
1192 : /*pe = HVQ_PE_WEIGHT2 * pe + (1 - HVQ_PE_WEIGHT2) * d; */
1193 3146 : Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT2B, &L_tmp, &lsb ); /* 12+15-15=12 */
1194 3146 : Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT2_FX, &L_pe, &lsb ); /* 12+15-15=12 */
1195 3146 : L_pe = L_add( L_pe, L_tmp ); /*Q12 */
1196 : }
1197 :
1198 4256 : L_nf_mean[i] = L_add_sat( L_nf_mean[i], L_nf ); /*Q12 */
1199 4256 : L_pe_mean[i] = L_add_sat( L_pe_mean[i], L_pe ); /*Q12 */
1200 4256 : move32();
1201 4256 : move32();
1202 4256 : IF( GT_32( L_d, L_peak ) )
1203 : {
1204 599 : L_peak = L_add( L_d, 0 );
1205 : }
1206 :
1207 4256 : q += 1;
1208 : }
1209 133 : L_nf_mean[i] = L_shr( L_nf_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
1210 133 : L_pe_mean[i] = L_shr( L_pe_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
1211 133 : move32();
1212 133 : move32();
1213 :
1214 : /*thr_tmp = (float)pow( pe_mean[i]/nf_mean[i], HVQ_THR_POW ) * nf_mean[i]; */
1215 133 : exp1 = norm_l( L_nf_mean[i] );
1216 133 : nf_mean_norm = extract_h( L_shl( L_nf_mean[i], exp1 ) ); /* 12+s-16=s-4 */
1217 133 : IF( nf_mean_norm == 0 )
1218 : {
1219 0 : inv_nf_mean = 0;
1220 : }
1221 : ELSE
1222 : {
1223 133 : inv_nf_mean = div_s( 1 << 14, nf_mean_norm ); /* 15+14-s+4=33-s */
1224 : }
1225 133 : Mpy_32_16_ss( L_pe_mean[i], inv_nf_mean, &L_tmp, &lsb ); /*12+33-s-15=30-s */
1226 :
1227 133 : exp2 = norm_l( L_tmp );
1228 133 : tmp = Log2_norm_lc( L_shl( L_tmp, exp2 ) ); /* Q15 */
1229 133 : exp2 = exp1 - exp2; /* Q0 */
1230 133 : L_tmp = Mpy_32_16( exp2, tmp, 32767 ); /* 1 in Q15. Q16 */
1231 133 : Mpy_32_16_ss( L_tmp, 28836, &L_tmp, &lsb ); /* 16+15-15=16 */
1232 133 : frac = L_Extract_lc( L_tmp, &tmp ); /* Q15 and Q0 */
1233 133 : L_tmp = Pow2( 14, frac ); /* Q14 */
1234 133 : L_tmp = L_shl( L_tmp, tmp ); /* Q14 */
1235 :
1236 133 : Mpy_32_16_ss( L_tmp, nf_mean_norm, &L_tmp, &lsb ); /*14+s-4-15=s-5 */
1237 133 : shift = sub( 17, exp1 ); /* 16-(s-5)=17-s */
1238 133 : L_thr_tmp = L_shl( L_tmp, shift ); /* Q16 */
1239 133 : L_thr_tmp = L_add( L_thr_tmp, lshr( lsb, sub( 16, shift ) ) ); /*Q16 */
1240 :
1241 133 : set32_fx( &L_thr[k], L_thr_tmp, HVQ_BW );
1242 133 : k = add( k, HVQ_BW );
1243 :
1244 : /*sharp[i] = peak/nf_mean[i]; */
1245 133 : Mpy_32_16_ss( L_peak, inv_nf_mean, &L_tmp, &lsb ); /* 12+33-s-15=30-s */
1246 133 : shift = sub( exp1, 8 );
1247 133 : sharp[i] = extract_h( L_shl( L_tmp, shift ) ); /* 30-s+s-8-16 -> Q6 */
1248 133 : move16();
1249 :
1250 : /*sharp_dist += (sharp[i]-HVQ_SHARP_THRES); */
1251 : #ifdef ISSUE_1867_replace_overflow_libenc
1252 133 : sharp_dist = add_sat( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ) );
1253 : #else
1254 : sharp_dist = add_o( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ), &Overflow );
1255 : #endif
1256 133 : IF( GT_16( sharp[i], HVQ_SHARP_THRES_FX ) )
1257 : {
1258 67 : num_sharp_bands = add( num_sharp_bands, 1 );
1259 : }
1260 : }
1261 :
1262 : /* Estimate noise floor gains */
1263 19 : offset = s_and( nsub, 1 );
1264 133 : FOR( i = 0; i < ( nsub & (Word16) 0xFFFE ); i++ )
1265 : {
1266 : /*(2*i+1)/nsub */
1267 114 : idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */
1268 114 : L_nf_gains[idx] = L_add( L_nf_gains[idx], L_nf_mean[i + offset] );
1269 114 : L_pe_gains[idx] = L_add( L_pe_gains[idx], L_pe_mean[i + offset] );
1270 114 : move32();
1271 114 : move32();
1272 : }
1273 :
1274 57 : FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
1275 : {
1276 38 : Mpy_32_16_ss( L_nf_gains[i], inv_gains_nsub, &L_nf_gains[i], &lsb ); /*12+15-15=12 */
1277 38 : Mpy_32_16_ss( L_pe_gains[i], inv_gains_nsub, &L_pe_gains[i], &lsb ); /*12+15-15=12 */
1278 : }
1279 :
1280 : /* Allocate available peaks */
1281 152 : FOR( i = 0; i < nsub; i++ )
1282 : {
1283 133 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP1;
1284 133 : move16();
1285 133 : idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */
1286 133 : Mpy_32_16_ss( L_nf_gains[idx], HVQ_PA_FAC_FX, &L_tmp, &lsb ); /* 12+15-15 -> Q12 */
1287 133 : IF( LT_32( L_nf_mean[i], L_tmp ) )
1288 : {
1289 39 : IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES3_FX ) )
1290 : {
1291 34 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP3;
1292 34 : move16();
1293 : }
1294 5 : ELSE IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES2_FX ) )
1295 : {
1296 4 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP2;
1297 4 : move16();
1298 : }
1299 : }
1300 : }
1301 :
1302 :
1303 : /* Adjust threshold around previous peaks */
1304 19 : FOR( i = 0; i < *prev_Npeaks; i++ )
1305 : {
1306 0 : j = sub( prev_peaks[i], 2 ); /* Q0 */
1307 0 : k = add( prev_peaks[i], 2 ); /* Q0 */
1308 0 : p_adj = hvq_thr_adj_fx; /* Q15 */
1309 0 : move16();
1310 :
1311 0 : FOR( q = j; q < k; q++ )
1312 : {
1313 0 : Mpy_32_16_ss( L_thr[q], *p_adj++, &L_thr[q], &lsb ); /* 12+15-15=12 */
1314 0 : move32();
1315 : }
1316 : }
1317 :
1318 19 : num_peak_cands = 0;
1319 19 : move16();
1320 :
1321 : /* Remove everything below threshold for peak search */
1322 19 : L_input_abs[0] = L_deposit_l( 0 );
1323 19 : L_input_abs[1] = L_deposit_l( 0 );
1324 19 : L_input_abs[N - 2] = L_deposit_l( 0 );
1325 19 : L_input_abs[N - 1] = L_deposit_l( 0 );
1326 19 : move32();
1327 19 : move32();
1328 19 : move32();
1329 19 : move32();
1330 4237 : FOR( i = 0; i < N - 2; i++ )
1331 : {
1332 4218 : IF( LT_32( L_input_abs[i], L_thr[i] ) )
1333 : {
1334 3120 : L_input_abs[i] = L_deposit_l( 0 );
1335 3120 : move32();
1336 : }
1337 : ELSE
1338 : {
1339 1098 : L_input_abs[num_peak_cands] = L_input_abs[i]; /* Q12 */
1340 1098 : move32();
1341 1098 : peak_cand_idx[num_peak_cands] = i; /* Q0 */
1342 1098 : move16();
1343 1098 : num_peak_cands = add( num_peak_cands, 1 );
1344 : }
1345 : }
1346 19 : IF( EQ_32( L_core_brate, HQ_24k40 ) )
1347 : {
1348 19 : peak_th = HVQ_MAX_PEAKS_24k_CLAS;
1349 19 : move16();
1350 : }
1351 : ELSE
1352 : {
1353 0 : peak_th = HVQ_MAX_PEAKS_32k;
1354 0 : move16();
1355 : }
1356 : /* Find peaks */
1357 19 : pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
1358 19 : i = 0;
1359 19 : move16();
1360 :
1361 461 : WHILE( L_m > 0 && LT_16( i, peak_th + 1 ) )
1362 : {
1363 442 : idx = mult( peak_cand_idx[pindx], INV_HVQ_BW ); /* 0+15-15=0 */
1364 442 : IF( avail_peaks[idx] > 0 )
1365 : {
1366 398 : peaks[i++] = peak_cand_idx[pindx]; /* Q0 */
1367 398 : move16();
1368 398 : avail_peaks[idx]--;
1369 : }
1370 :
1371 442 : j = sub( pindx, 2 );
1372 442 : k = add( pindx, 2 );
1373 :
1374 442 : if ( j < 0 )
1375 : {
1376 19 : j = 0;
1377 19 : move16();
1378 : }
1379 :
1380 442 : tmp = sub( num_peak_cands, 1 );
1381 442 : if ( GT_16( k, tmp ) )
1382 : {
1383 17 : k = tmp;
1384 17 : move16();
1385 : }
1386 :
1387 442 : low = sub( peak_cand_idx[pindx], 2 );
1388 442 : high = add( peak_cand_idx[pindx], 2 );
1389 :
1390 442 : if ( low < 0 )
1391 : {
1392 0 : low = 0;
1393 0 : move16();
1394 : }
1395 :
1396 442 : tmp = sub( N, 1 );
1397 442 : IF( GT_16( high, tmp ) )
1398 : {
1399 0 : high = tmp;
1400 0 : move16();
1401 : }
1402 :
1403 1738 : FOR( q = j; q <= pindx; q++ )
1404 : {
1405 1296 : IF( GE_16( peak_cand_idx[q], low ) )
1406 : {
1407 649 : peak_cand_idx[q] = 0;
1408 649 : move16();
1409 649 : L_input_abs[q] = 0;
1410 649 : move16();
1411 : }
1412 : }
1413 :
1414 1299 : FOR( q = pindx + 1; q <= k; q++ )
1415 : {
1416 857 : IF( LE_16( peak_cand_idx[q], high ) )
1417 : {
1418 529 : peak_cand_idx[q] = 0;
1419 529 : move16();
1420 529 : L_input_abs[q] = 0;
1421 529 : move16();
1422 : }
1423 : }
1424 :
1425 442 : pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m ); /* Q0 */
1426 : }
1427 :
1428 19 : *Npeaks = i;
1429 19 : move16();
1430 19 : IF( GT_16( *Npeaks, HVQ_MIN_PEAKS ) )
1431 : {
1432 19 : test();
1433 19 : IF( GT_16( num_sharp_bands, sub( nsub, 3 ) ) && LE_16( *Npeaks, peak_th ) )
1434 : {
1435 0 : sharp_dist = mult( sharp_dist, inv_nsub ); /*x+15-15=x */
1436 0 : test();
1437 0 : IF( LE_16( sharp_dist, SHARP_DIST_THRES_FX ) && *hvq_hangover < 0 )
1438 : {
1439 0 : *hvq_hangover = add( *hvq_hangover, 1 );
1440 : }
1441 : ELSE
1442 : {
1443 0 : *hqswb_clas = HQ_HVQ; /* Q0 */
1444 0 : move16();
1445 0 : *hvq_hangover = 2; /* Q0 */
1446 0 : move16();
1447 : }
1448 :
1449 : /* update memory */
1450 0 : *prev_Npeaks = *Npeaks; /* Q0 */
1451 0 : move16();
1452 0 : Copy( peaks, prev_peaks, *Npeaks ); /* Q0 */
1453 : }
1454 : ELSE
1455 : {
1456 19 : IF( *hvq_hangover > 0 )
1457 : {
1458 0 : *hqswb_clas = HQ_HVQ; /* Q0 */
1459 0 : move16();
1460 0 : *hvq_hangover = sub( *hvq_hangover, 1 ); /* Q0 */
1461 0 : move16();
1462 : }
1463 : ELSE
1464 : {
1465 19 : *hvq_hangover = -1;
1466 19 : move16();
1467 : }
1468 : }
1469 : }
1470 : ELSE
1471 : {
1472 : /* Zero peaks, likely silence input. */
1473 0 : *hvq_hangover = -1;
1474 0 : move16();
1475 : }
1476 :
1477 19 : IF( EQ_32( L_core_brate, HQ_24k40 ) )
1478 : {
1479 19 : *Npeaks = s_min( HVQ_MAX_PEAKS_24k, *Npeaks ); /* Q0 */
1480 19 : move16();
1481 : }
1482 : ELSE
1483 : {
1484 0 : *Npeaks = s_min( HVQ_MAX_PEAKS_32k, *Npeaks ); /* Q0 */
1485 0 : move16();
1486 : }
1487 : }
1488 : ELSE
1489 : {
1490 47 : *prev_Npeaks = 0;
1491 47 : move16();
1492 47 : *hvq_hangover = 0;
1493 47 : move16();
1494 : }
1495 :
1496 :
1497 66 : return;
1498 : }
|