Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include "options.h" /* Compilation switches */
7 : #include "cnst.h" /* Common constants */
8 : #include "rom_com.h" /* Static table prototypes */
9 : #include "prot_fx.h" /* Function prototypes */
10 : #include "prot_fx_enc.h" /* Function prototypes */
11 :
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( Encoder_State *st, const Word32 *coefs_fx );
32 :
33 :
34 : /*--------------------------------------------------------------------------*
35 : * hf_spectrum_sparseness()
36 : *
37 : * Detection of sparse spectrum in high band for activation of harmonic
38 : * modes HQ_HARMONIC and HQ_HVQ
39 : *--------------------------------------------------------------------------*/
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 6696 : Word16 temp_e = 0;
656 6696 : move16();
657 :
658 6696 : L_input_max = L_deposit_l( 0 );
659 6696 : set32_fx( L_thr, 0, L_FRAME16k );
660 :
661 6696 : IF( LT_32( L_core_brate, HQ_BWE_CROSSOVER_BRATE ) )
662 : {
663 2654 : nsub = HVQ_NSUB_24k;
664 2654 : move16();
665 2654 : inv_nsub = 4681; /* 1/7 in Q15 */
666 2654 : move16();
667 2654 : inv_gains_nsub = 10923; /* 1/3 in Q15 */
668 2654 : move16();
669 : }
670 : ELSE
671 : {
672 4042 : nsub = HVQ_NSUB_32k;
673 4042 : move16();
674 4042 : inv_nsub = 3277; /* 1/10 in Q15 */
675 4042 : move16();
676 4042 : inv_gains_nsub = 6554; /* 1/5 in Q15 */
677 4042 : move16();
678 : }
679 :
680 6696 : N = shl( nsub, 5 ); /* Mult by 32 (HVQ_BW) */
681 :
682 6696 : test();
683 6696 : test();
684 6696 : IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && last_core != ACELP_CORE && NE_16( last_core, AMR_WB_CORE ) )
685 2228 : {
686 597300 : FOR( i = 0; i < N; i++ )
687 : {
688 595072 : L_input_abs[i] = L_abs( input[i] ); /* Q12 */
689 595072 : move16();
690 595072 : IF( GT_32( L_input_abs[i], L_input_max ) )
691 : {
692 13556 : L_input_max = L_input_abs[i]; /* Q12 */
693 13556 : move16();
694 : }
695 : }
696 :
697 2228 : exp1 = norm_l( L_input_max );
698 :
699 2228 : *Npeaks = 0;
700 2228 : move16();
701 2228 : L_nf = 3276800; /* 800 in Q12 */
702 2228 : move32();
703 2228 : L_pe = 3276800; /* 800 in Q12 */
704 2228 : move32();
705 2228 : num_sharp_bands = 0;
706 2228 : move16();
707 2228 : k = 0;
708 2228 : move16();
709 2228 : q = 0;
710 2228 : move16();
711 2228 : sharp_dist = 0;
712 2228 : move16();
713 :
714 : /* Find peak threshold */
715 20824 : FOR( i = 0; i < nsub; i++ )
716 : {
717 18596 : L_peak = 0;
718 18596 : L_nf_mean[i] = 0;
719 18596 : L_pe_mean[i] = 0;
720 18596 : move32();
721 18596 : move32();
722 18596 : move32();
723 :
724 613668 : FOR( j = 0; j < HVQ_BW; j++ )
725 : {
726 595072 : L_d = L_input_abs[q]; /* Q12 */
727 595072 : IF( GT_32( L_d, L_nf ) )
728 : {
729 : /*nf = HVQ_NF_WEIGHT1 * nf + (1 - HVQ_NF_WEIGHT1) * d; */
730 317930 : Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT1B, &L_tmp, &lsb ); /* 12+15-15=12 */
731 317930 : Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT1_FX, &L_nf, &lsb ); /* 12+15-15=12 */
732 317930 : L_nf = L_add( L_nf, L_tmp ); /*Q12 */
733 : }
734 : ELSE
735 : {
736 : /*nf = HVQ_NF_WEIGHT2 * nf + (1 - HVQ_NF_WEIGHT2) * d; */
737 277142 : Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT2B, &L_tmp, &lsb ); /* 12+15-15=12 */
738 277142 : Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT2_FX, &L_nf, &lsb ); /* 12+15-15=12 */
739 277142 : L_nf = L_add( L_nf, L_tmp ); /*Q12 */
740 : }
741 :
742 595072 : IF( GT_32( L_d, L_pe ) )
743 : {
744 : /*pe = HVQ_PE_WEIGHT1 * pe + (1 - HVQ_PE_WEIGHT1) * d; */
745 118938 : Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT1B, &L_tmp, &lsb ); /* 12+15-15=12 */
746 118938 : Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT1_FX, &L_pe, &lsb ); /* 12+15-15=12 */
747 118938 : L_pe = L_add( L_pe, L_tmp ); /*Q12 */
748 : }
749 : ELSE
750 : {
751 : /*pe = HVQ_PE_WEIGHT2 * pe + (1 - HVQ_PE_WEIGHT2) * d; */
752 476134 : Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT2B, &L_tmp, &lsb ); /* 12+15-15=12 */
753 476134 : Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT2_FX, &L_pe, &lsb ); /* 12+15-15=12 */
754 476134 : L_pe = L_add( L_pe, L_tmp ); /*Q12 */
755 : }
756 :
757 595072 : L_nf_mean[i] = L_add_sat( L_nf_mean[i], L_nf ); /*Q12 */
758 595072 : L_pe_mean[i] = L_add_sat( L_pe_mean[i], L_pe ); /*Q12 */
759 595072 : move32();
760 595072 : move32();
761 595072 : IF( GT_32( L_d, L_peak ) )
762 : {
763 89235 : L_peak = L_add( L_d, 0 );
764 : }
765 :
766 595072 : q += 1;
767 : }
768 18596 : L_nf_mean[i] = L_shr( L_nf_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
769 18596 : L_pe_mean[i] = L_shr( L_pe_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
770 18596 : move32();
771 18596 : move32();
772 : /*thr_tmp = (float)pow( pe_mean[i]/nf_mean[i], HVQ_THR_POW ) * nf_mean[i]; */
773 18596 : exp1 = norm_l( L_nf_mean[i] );
774 18596 : nf_mean_norm = extract_h( L_shl( L_nf_mean[i], exp1 ) ); /* 12+s-16=s-4 */
775 18596 : IF( nf_mean_norm == 0 )
776 : {
777 0 : inv_nf_mean = 0;
778 : }
779 : ELSE
780 : {
781 18596 : inv_nf_mean = div_s( 1 << 14, nf_mean_norm ); /* 15+14-s+4=33-s */
782 : }
783 18596 : Mpy_32_16_ss( L_pe_mean[i], inv_nf_mean, &L_tmp, &lsb ); /*12+33-s-15=30-s */
784 :
785 18596 : exp2 = norm_l( L_tmp );
786 18596 : tmp = Log2_norm_lc( L_shl( L_tmp, exp2 ) ); /* Q15 */
787 18596 : exp2 = sub( exp1, exp2 ); /* Q0 */
788 18596 : L_tmp = Mpy_32_16( exp2, tmp, 32767 ); /* 1 in Q15. Q16 */
789 18596 : Mpy_32_16_ss( L_tmp, 28836, &L_tmp, &lsb ); /* 16+15-15=16 */
790 18596 : frac = L_Extract_lc( L_tmp, &tmp ); /* Q15 and Q0 */
791 18596 : L_tmp = Pow2( 14, frac ); /* Q14 */
792 18596 : L_tmp = L_shl( L_tmp, tmp ); /* Q14 */
793 :
794 18596 : Mpy_32_16_ss( L_tmp, nf_mean_norm, &L_tmp, &lsb ); /*14+s-4-15=s-5 */
795 18596 : shift = sub( 17, exp1 ); /* 16-(s-5)=17-s */
796 18596 : L_thr_tmp = L_shl( L_tmp, shift ); /* Q16 */
797 18596 : L_thr_tmp = L_add( L_thr_tmp, lshr( lsb, sub( 16, shift ) ) ); /*Q16 */
798 :
799 18596 : set32_fx( &L_thr[k], L_thr_tmp, HVQ_BW );
800 18596 : k = add( k, HVQ_BW );
801 :
802 : /*sharp[i] = peak/nf_mean[i]; */
803 18596 : Mpy_32_16_ss( L_peak, inv_nf_mean, &L_tmp, &lsb ); /* 12+33-s-15=30-s */
804 18596 : shift = sub( exp1, 8 );
805 18596 : sharp[i] = extract_h( L_shl( L_tmp, shift ) ); /* 30-s+s-8-16 -> Q6 */
806 18596 : move16();
807 : /*sharp_dist += (sharp[i]-HVQ_SHARP_THRES); */
808 18596 : sharp_dist = add_sat( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ) ); /* Q6 */
809 18596 : if ( GT_16( sharp[i], HVQ_SHARP_THRES_FX ) )
810 : {
811 16013 : num_sharp_bands = add( num_sharp_bands, 1 );
812 : }
813 : }
814 :
815 : /* Estimate noise floor gains */
816 2228 : offset = s_and( nsub, 1 );
817 19596 : FOR( i = 0; i < ( nsub & (Word16) 0xFFFE ); i++ )
818 : {
819 : /*(2*i+1)/nsub */
820 17368 : idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */
821 17368 : L_nf_gains[idx] = L_add( L_nf_gains[idx], L_nf_mean[i + offset] ); /* Q12 */
822 17368 : L_pe_gains[idx] = L_add( L_pe_gains[idx], L_pe_mean[i + offset] ); /* Q12 */
823 17368 : move32();
824 17368 : move32();
825 : }
826 :
827 6684 : FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
828 : {
829 4456 : Mpy_32_16_ss( L_nf_gains[i], inv_gains_nsub, &L_nf_gains[i], &lsb ); /*12+15-15=12 */
830 4456 : Mpy_32_16_ss( L_pe_gains[i], inv_gains_nsub, &L_pe_gains[i], &lsb ); /*12+15-15=12 */
831 : }
832 :
833 : /* Allocate available peaks */
834 20824 : FOR( i = 0; i < nsub; i++ )
835 : {
836 18596 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP1; /* Q0 */
837 18596 : move16();
838 18596 : idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */
839 18596 : Mpy_32_16_ss( L_nf_gains[idx], HVQ_PA_FAC_FX, &L_tmp, &lsb ); /* 12+15-15 -> Q12 */
840 18596 : IF( LT_32( L_nf_mean[i], L_tmp ) )
841 : {
842 6684 : IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES3_FX ) )
843 : {
844 1487 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP3; /* Q0 */
845 1487 : move16();
846 : }
847 5197 : ELSE IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES2_FX ) )
848 : {
849 673 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP2; /* Q0 */
850 673 : move16();
851 : }
852 : }
853 : }
854 :
855 :
856 : /* Adjust threshold around previous peaks */
857 27058 : FOR( i = 0; i < *prev_Npeaks; i++ )
858 : {
859 24830 : j = sub( prev_peaks[i], 2 ); /* Q0 */
860 24830 : k = add( prev_peaks[i], 2 ); /* Q0 */
861 24830 : p_adj = hvq_thr_adj_fx; /* Q15 */
862 :
863 124150 : FOR( q = j; q < k; q++ )
864 : {
865 99320 : Mpy_32_16_ss( L_thr[q], *p_adj++, &L_thr[q], &lsb ); /* 12+15-15=12 */
866 99320 : move32();
867 : }
868 : }
869 :
870 2228 : num_peak_cands = 0;
871 2228 : move16();
872 :
873 : /* Remove everything below threshold for peak search */
874 2228 : L_input_abs[0] = L_deposit_l( 0 );
875 2228 : L_input_abs[1] = L_deposit_l( 0 );
876 2228 : L_input_abs[N - 2] = L_deposit_l( 0 );
877 2228 : L_input_abs[N - 1] = L_deposit_l( 0 );
878 2228 : move32();
879 2228 : move32();
880 2228 : move32();
881 2228 : move32();
882 592844 : FOR( i = 0; i < N - 2; i++ )
883 : {
884 590616 : IF( LT_32( L_input_abs[i], L_thr[i] ) )
885 : {
886 481953 : L_input_abs[i] = L_deposit_l( 0 );
887 :
888 481953 : move32();
889 : }
890 : ELSE
891 : {
892 108663 : L_input_abs[num_peak_cands] = L_input_abs[i]; /* Q12 */
893 108663 : move32();
894 108663 : peak_cand_idx[num_peak_cands] = i; /* Q0 */
895 108663 : move16();
896 108663 : num_peak_cands = add( num_peak_cands, 1 );
897 : }
898 : }
899 :
900 :
901 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 ) );
902 2228 : peak_th = shr( peak_th, sub( 15, temp_e ) );
903 : /* Find peaks */
904 2228 : pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
905 2228 : i = 0;
906 2228 : move16();
907 :
908 46676 : WHILE( L_m > 0 && LT_16( i, peak_th + 1 ) )
909 : {
910 44448 : idx = mult( peak_cand_idx[pindx], INV_HVQ_BW ); /* 0+15-15=0 */
911 44448 : IF( avail_peaks[idx] > 0 )
912 : {
913 43425 : peaks[i++] = peak_cand_idx[pindx]; /* Q0 */
914 43425 : avail_peaks[idx]--;
915 : }
916 :
917 44448 : j = sub( pindx, 2 );
918 44448 : k = add( pindx, 2 );
919 :
920 44448 : if ( j < 0 )
921 : {
922 2165 : j = 0;
923 2165 : move16();
924 : }
925 :
926 44448 : tmp = sub( num_peak_cands, 1 );
927 44448 : if ( GT_16( k, tmp ) )
928 : {
929 1559 : k = tmp;
930 1559 : move16();
931 : }
932 :
933 44448 : low = sub( peak_cand_idx[pindx], 2 );
934 44448 : high = add( peak_cand_idx[pindx], 2 );
935 :
936 44448 : if ( low < 0 )
937 : {
938 0 : low = 0;
939 0 : move16();
940 : }
941 :
942 44448 : tmp = sub( N, 1 );
943 44448 : if ( GT_16( high, tmp ) )
944 : {
945 0 : high = tmp;
946 0 : move16();
947 : }
948 :
949 174331 : FOR( q = j; q <= pindx; q++ )
950 : {
951 129883 : IF( GE_16( peak_cand_idx[q], low ) )
952 : {
953 73442 : peak_cand_idx[q] = 0;
954 73442 : move16();
955 73442 : L_input_abs[q] = 0;
956 73442 : move16();
957 : }
958 : }
959 :
960 130973 : FOR( q = pindx + 1; q <= k; q++ )
961 : {
962 86525 : IF( LE_16( peak_cand_idx[q], high ) )
963 : {
964 59481 : peak_cand_idx[q] = 0;
965 59481 : move16();
966 59481 : L_input_abs[q] = 0;
967 59481 : move16();
968 : }
969 : }
970 :
971 44448 : pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
972 : }
973 :
974 2228 : *Npeaks = i; /* Q0 */
975 2228 : move16();
976 2228 : IF( GT_16( *Npeaks, HVQ_MIN_PEAKS ) )
977 : {
978 2228 : test();
979 2228 : IF( GT_16( num_sharp_bands, sub( nsub, 3 ) ) && LE_16( *Npeaks, peak_th ) )
980 : {
981 1231 : sharp_dist = mult( sharp_dist, inv_nsub ); /*x+15-15=x */
982 1231 : test();
983 1231 : IF( LE_16( sharp_dist, SHARP_DIST_THRES_FX ) && *hvq_hangover < 0 )
984 : {
985 39 : *hvq_hangover = add( *hvq_hangover, 1 ); /* Q0 */
986 : }
987 : ELSE
988 : {
989 1192 : *hqswb_clas = HQ_HVQ; /* Q0 */
990 1192 : move16();
991 1192 : *hvq_hangover = 2; /* Q0 */
992 1192 : move16();
993 : }
994 :
995 : /* update memory */
996 1231 : *prev_Npeaks = *Npeaks; /* Q0 */
997 1231 : move16();
998 1231 : Copy( peaks, prev_peaks, *Npeaks ); /* Q0 */
999 : }
1000 : ELSE
1001 : {
1002 997 : IF( *hvq_hangover > 0 )
1003 : {
1004 275 : *hqswb_clas = HQ_HVQ; /* Q0 */
1005 275 : move16();
1006 275 : *hvq_hangover = sub( *hvq_hangover, 1 ); /* Q0 */
1007 275 : move16();
1008 : }
1009 : ELSE
1010 : {
1011 722 : *hvq_hangover = -1;
1012 722 : move16();
1013 : }
1014 : }
1015 : }
1016 : ELSE
1017 : {
1018 : /* Zero peaks, likely silence input. */
1019 0 : *hvq_hangover = -1;
1020 0 : move16();
1021 : }
1022 :
1023 : //*Npeaks = (int16_t) ( s_min( ( L_core_brate * HVQ_PEAKS_PER_DELTA + HVQ_PEAKS_PER_DELTA_OFFS ) / HVQ_PEAKS_BPS_DELTA, *Npeaks ) );
1024 2228 : temp_e = 0;
1025 2228 : move16();
1026 2228 : Word16 Npeaks_temp = *Npeaks;
1027 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 );
1028 2228 : *Npeaks = s_min( shr( *Npeaks, sub( 15, temp_e ) ), Npeaks_temp );
1029 2228 : move16();
1030 : }
1031 : ELSE
1032 : {
1033 4468 : *prev_Npeaks = 0;
1034 4468 : move16();
1035 4468 : *hvq_hangover = 0;
1036 4468 : move16();
1037 : }
1038 :
1039 :
1040 6696 : return;
1041 : }
1042 :
1043 66 : void hvq_classifier_fx(
1044 : const Word32 *input, /* i : input signal Q12 */
1045 : Word16 *prev_Npeaks, /* i/o: Peak number memory Q0 */
1046 : Word16 *prev_peaks, /* i/o: Peak indices memory Q0 */
1047 : Word16 *hqswb_clas, /* i/o: HQ class Q0 */
1048 : Word16 *Npeaks, /* o : Number of peaks Q0 */
1049 : Word16 *peaks, /* o : Peak indices Q0 */
1050 : const Word32 L_core_brate, /* i : Core bit-rate Q0 */
1051 : const Word16 last_core, /* i : Last core used Q0 */
1052 : Word32 *L_nf_gains, /* o : Noisefloor gains Q12 */
1053 : Word16 *hvq_hangover, /* i/o: Mode-switch hangover Q0 */
1054 : Word32 *L_pe_gains /* o : peak gains Q12 */
1055 : )
1056 : {
1057 : const Word16 *p_adj;
1058 : UWord16 lsb;
1059 :
1060 : Word32 L_input_abs[L_FRAME32k];
1061 : Word32 L_input_max;
1062 : Word32 L_thr[L_FRAME16k];
1063 : Word32 L_thr_tmp;
1064 : Word32 L_m;
1065 : Word32 L_tmp;
1066 : Word32 L_d;
1067 : Word32 L_peak;
1068 : Word32 L_nf, L_pe;
1069 : Word32 L_pe_mean[HVQ_NSUB_32k], L_nf_mean[HVQ_NSUB_32k];
1070 :
1071 : Word16 inv_nsub;
1072 : Word16 sharp_dist;
1073 : Word16 exp1, exp2;
1074 : Word16 tmp;
1075 : Word16 shift;
1076 : Word16 idx;
1077 : Word16 frac;
1078 : Word16 inv_nf_mean;
1079 : Word16 inv_gains_nsub;
1080 : Word16 nf_mean_norm;
1081 : Word16 num_sharp_bands, i, j, k, q, peak_th, nsub, pindx, N, offset;
1082 : Word16 num_peak_cands, high, low;
1083 : Word16 sharp[HVQ_NSUB_32k];
1084 : Word16 peak_cand_idx[HVQ_THRES_BIN_32k], avail_peaks[HVQ_NSUB_32k];
1085 :
1086 66 : L_input_max = L_deposit_l( 0 );
1087 66 : set32_fx( L_thr, 0, L_FRAME16k );
1088 :
1089 66 : IF( EQ_32( L_core_brate, HQ_24k40 ) )
1090 : {
1091 66 : nsub = HVQ_NSUB_24k;
1092 66 : move16();
1093 66 : inv_nsub = 4681; /* 1/7 in Q15 */
1094 66 : move16();
1095 66 : inv_gains_nsub = 10923; /* 1/3 in Q15 */
1096 66 : move16();
1097 : }
1098 : ELSE
1099 : {
1100 0 : nsub = HVQ_NSUB_32k;
1101 0 : move16();
1102 0 : inv_nsub = 3277; /* 1/10 in Q15 */
1103 0 : move16();
1104 0 : inv_gains_nsub = 6554; /* 1/5 in Q15 */
1105 0 : move16();
1106 : }
1107 :
1108 66 : N = shl( nsub, 5 ); /* Mult by 32 (HVQ_BW) */
1109 :
1110 66 : test();
1111 66 : test();
1112 66 : IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && last_core != ACELP_CORE && NE_16( last_core, AMR_WB_CORE ) )
1113 : {
1114 4275 : FOR( i = 0; i < N; i++ )
1115 : {
1116 4256 : L_input_abs[i] = L_abs( input[i] ); /* Q12 */
1117 4256 : IF( GT_32( L_input_abs[i], L_input_max ) )
1118 : {
1119 104 : L_input_max = L_input_abs[i]; /* Q12 */
1120 104 : move16();
1121 : }
1122 : }
1123 :
1124 19 : exp1 = norm_l( L_input_max );
1125 :
1126 19 : *Npeaks = 0;
1127 19 : move16();
1128 19 : L_nf = 3276800; /* 800 in Q12 */
1129 19 : move32();
1130 19 : L_pe = 3276800; /* 800 in Q12 */
1131 19 : move32();
1132 19 : num_sharp_bands = 0;
1133 19 : move16();
1134 19 : k = 0;
1135 19 : move16();
1136 19 : q = 0;
1137 19 : move16();
1138 19 : sharp_dist = 0;
1139 19 : move16();
1140 :
1141 : /* Find peak threshold */
1142 152 : FOR( i = 0; i < nsub; i++ )
1143 : {
1144 133 : L_peak = 0;
1145 133 : L_nf_mean[i] = 0;
1146 133 : L_pe_mean[i] = 0;
1147 133 : move32();
1148 133 : move32();
1149 133 : move32();
1150 4389 : FOR( j = 0; j < HVQ_BW; j++ )
1151 : {
1152 4256 : L_d = L_input_abs[q]; /* Q12 */
1153 4256 : move32();
1154 4256 : IF( GT_32( L_d, L_nf ) )
1155 : {
1156 : /*nf = HVQ_NF_WEIGHT1 * nf + (1 - HVQ_NF_WEIGHT1) * d; */
1157 2763 : Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT1B, &L_tmp, &lsb ); /* 12+15-15=12 */
1158 2763 : Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT1_FX, &L_nf, &lsb ); /* 12+15-15=12 */
1159 2763 : L_nf = L_add( L_nf, L_tmp ); /*Q12 */
1160 : }
1161 : ELSE
1162 : {
1163 : /*nf = HVQ_NF_WEIGHT2 * nf + (1 - HVQ_NF_WEIGHT2) * d; */
1164 1493 : Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT2B, &L_tmp, &lsb ); /* 12+15-15=12 */
1165 1493 : Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT2_FX, &L_nf, &lsb ); /* 12+15-15=12 */
1166 1493 : L_nf = L_add( L_nf, L_tmp ); /*Q12 */
1167 : }
1168 :
1169 4256 : IF( GT_32( L_d, L_pe ) )
1170 : {
1171 : /*pe = HVQ_PE_WEIGHT1 * pe + (1 - HVQ_PE_WEIGHT1) * d; */
1172 1110 : Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT1B, &L_tmp, &lsb ); /* 12+15-15=12 */
1173 1110 : Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT1_FX, &L_pe, &lsb ); /* 12+15-15=12 */
1174 1110 : L_pe = L_add( L_pe, L_tmp ); /*Q12 */
1175 : }
1176 : ELSE
1177 : {
1178 : /*pe = HVQ_PE_WEIGHT2 * pe + (1 - HVQ_PE_WEIGHT2) * d; */
1179 3146 : Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT2B, &L_tmp, &lsb ); /* 12+15-15=12 */
1180 3146 : Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT2_FX, &L_pe, &lsb ); /* 12+15-15=12 */
1181 3146 : L_pe = L_add( L_pe, L_tmp ); /*Q12 */
1182 : }
1183 :
1184 4256 : L_nf_mean[i] = L_add_sat( L_nf_mean[i], L_nf ); /*Q12 */
1185 4256 : L_pe_mean[i] = L_add_sat( L_pe_mean[i], L_pe ); /*Q12 */
1186 4256 : move32();
1187 4256 : move32();
1188 4256 : IF( GT_32( L_d, L_peak ) )
1189 : {
1190 599 : L_peak = L_add( L_d, 0 );
1191 : }
1192 :
1193 4256 : q += 1;
1194 : }
1195 133 : L_nf_mean[i] = L_shr( L_nf_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
1196 133 : L_pe_mean[i] = L_shr( L_pe_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
1197 133 : move32();
1198 133 : move32();
1199 :
1200 : /*thr_tmp = (float)pow( pe_mean[i]/nf_mean[i], HVQ_THR_POW ) * nf_mean[i]; */
1201 133 : exp1 = norm_l( L_nf_mean[i] );
1202 133 : nf_mean_norm = extract_h( L_shl( L_nf_mean[i], exp1 ) ); /* 12+s-16=s-4 */
1203 133 : IF( nf_mean_norm == 0 )
1204 : {
1205 0 : inv_nf_mean = 0;
1206 : }
1207 : ELSE
1208 : {
1209 133 : inv_nf_mean = div_s( 1 << 14, nf_mean_norm ); /* 15+14-s+4=33-s */
1210 : }
1211 133 : Mpy_32_16_ss( L_pe_mean[i], inv_nf_mean, &L_tmp, &lsb ); /*12+33-s-15=30-s */
1212 :
1213 133 : exp2 = norm_l( L_tmp );
1214 133 : tmp = Log2_norm_lc( L_shl( L_tmp, exp2 ) ); /* Q15 */
1215 133 : exp2 = exp1 - exp2; /* Q0 */
1216 133 : L_tmp = Mpy_32_16( exp2, tmp, 32767 ); /* 1 in Q15. Q16 */
1217 133 : Mpy_32_16_ss( L_tmp, 28836, &L_tmp, &lsb ); /* 16+15-15=16 */
1218 133 : frac = L_Extract_lc( L_tmp, &tmp ); /* Q15 and Q0 */
1219 133 : L_tmp = Pow2( 14, frac ); /* Q14 */
1220 133 : L_tmp = L_shl( L_tmp, tmp ); /* Q14 */
1221 :
1222 133 : Mpy_32_16_ss( L_tmp, nf_mean_norm, &L_tmp, &lsb ); /*14+s-4-15=s-5 */
1223 133 : shift = sub( 17, exp1 ); /* 16-(s-5)=17-s */
1224 133 : L_thr_tmp = L_shl( L_tmp, shift ); /* Q16 */
1225 133 : L_thr_tmp = L_add( L_thr_tmp, lshr( lsb, sub( 16, shift ) ) ); /*Q16 */
1226 :
1227 133 : set32_fx( &L_thr[k], L_thr_tmp, HVQ_BW );
1228 133 : k = add( k, HVQ_BW );
1229 :
1230 : /*sharp[i] = peak/nf_mean[i]; */
1231 133 : Mpy_32_16_ss( L_peak, inv_nf_mean, &L_tmp, &lsb ); /* 12+33-s-15=30-s */
1232 133 : shift = sub( exp1, 8 );
1233 133 : sharp[i] = extract_h( L_shl( L_tmp, shift ) ); /* 30-s+s-8-16 -> Q6 */
1234 133 : move16();
1235 :
1236 : /*sharp_dist += (sharp[i]-HVQ_SHARP_THRES); */
1237 133 : sharp_dist = add_sat( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ) );
1238 133 : IF( GT_16( sharp[i], HVQ_SHARP_THRES_FX ) )
1239 : {
1240 67 : num_sharp_bands = add( num_sharp_bands, 1 );
1241 : }
1242 : }
1243 :
1244 : /* Estimate noise floor gains */
1245 19 : offset = s_and( nsub, 1 );
1246 133 : FOR( i = 0; i < ( nsub & (Word16) 0xFFFE ); i++ )
1247 : {
1248 : /*(2*i+1)/nsub */
1249 114 : idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */
1250 114 : L_nf_gains[idx] = L_add( L_nf_gains[idx], L_nf_mean[i + offset] );
1251 114 : L_pe_gains[idx] = L_add( L_pe_gains[idx], L_pe_mean[i + offset] );
1252 114 : move32();
1253 114 : move32();
1254 : }
1255 :
1256 57 : FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
1257 : {
1258 38 : Mpy_32_16_ss( L_nf_gains[i], inv_gains_nsub, &L_nf_gains[i], &lsb ); /*12+15-15=12 */
1259 38 : Mpy_32_16_ss( L_pe_gains[i], inv_gains_nsub, &L_pe_gains[i], &lsb ); /*12+15-15=12 */
1260 : }
1261 :
1262 : /* Allocate available peaks */
1263 152 : FOR( i = 0; i < nsub; i++ )
1264 : {
1265 133 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP1;
1266 133 : move16();
1267 133 : idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */
1268 133 : Mpy_32_16_ss( L_nf_gains[idx], HVQ_PA_FAC_FX, &L_tmp, &lsb ); /* 12+15-15 -> Q12 */
1269 133 : IF( LT_32( L_nf_mean[i], L_tmp ) )
1270 : {
1271 39 : IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES3_FX ) )
1272 : {
1273 34 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP3;
1274 34 : move16();
1275 : }
1276 5 : ELSE IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES2_FX ) )
1277 : {
1278 4 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP2;
1279 4 : move16();
1280 : }
1281 : }
1282 : }
1283 :
1284 :
1285 : /* Adjust threshold around previous peaks */
1286 19 : FOR( i = 0; i < *prev_Npeaks; i++ )
1287 : {
1288 0 : j = sub( prev_peaks[i], 2 ); /* Q0 */
1289 0 : k = add( prev_peaks[i], 2 ); /* Q0 */
1290 0 : p_adj = hvq_thr_adj_fx; /* Q15 */
1291 0 : move16();
1292 :
1293 0 : FOR( q = j; q < k; q++ )
1294 : {
1295 0 : Mpy_32_16_ss( L_thr[q], *p_adj++, &L_thr[q], &lsb ); /* 12+15-15=12 */
1296 0 : move32();
1297 : }
1298 : }
1299 :
1300 19 : num_peak_cands = 0;
1301 19 : move16();
1302 :
1303 : /* Remove everything below threshold for peak search */
1304 19 : L_input_abs[0] = L_deposit_l( 0 );
1305 19 : L_input_abs[1] = L_deposit_l( 0 );
1306 19 : L_input_abs[N - 2] = L_deposit_l( 0 );
1307 19 : L_input_abs[N - 1] = L_deposit_l( 0 );
1308 19 : move32();
1309 19 : move32();
1310 19 : move32();
1311 19 : move32();
1312 4237 : FOR( i = 0; i < N - 2; i++ )
1313 : {
1314 4218 : IF( LT_32( L_input_abs[i], L_thr[i] ) )
1315 : {
1316 3120 : L_input_abs[i] = L_deposit_l( 0 );
1317 3120 : move32();
1318 : }
1319 : ELSE
1320 : {
1321 1098 : L_input_abs[num_peak_cands] = L_input_abs[i]; /* Q12 */
1322 1098 : move32();
1323 1098 : peak_cand_idx[num_peak_cands] = i; /* Q0 */
1324 1098 : move16();
1325 1098 : num_peak_cands = add( num_peak_cands, 1 );
1326 : }
1327 : }
1328 19 : IF( EQ_32( L_core_brate, HQ_24k40 ) )
1329 : {
1330 19 : peak_th = HVQ_MAX_PEAKS_24k_CLAS;
1331 19 : move16();
1332 : }
1333 : ELSE
1334 : {
1335 0 : peak_th = HVQ_MAX_PEAKS_32k;
1336 0 : move16();
1337 : }
1338 : /* Find peaks */
1339 19 : pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
1340 19 : i = 0;
1341 19 : move16();
1342 :
1343 461 : WHILE( L_m > 0 && LT_16( i, peak_th + 1 ) )
1344 : {
1345 442 : idx = mult( peak_cand_idx[pindx], INV_HVQ_BW ); /* 0+15-15=0 */
1346 442 : IF( avail_peaks[idx] > 0 )
1347 : {
1348 398 : peaks[i++] = peak_cand_idx[pindx]; /* Q0 */
1349 398 : move16();
1350 398 : avail_peaks[idx]--;
1351 : }
1352 :
1353 442 : j = sub( pindx, 2 );
1354 442 : k = add( pindx, 2 );
1355 :
1356 442 : if ( j < 0 )
1357 : {
1358 19 : j = 0;
1359 19 : move16();
1360 : }
1361 :
1362 442 : tmp = sub( num_peak_cands, 1 );
1363 442 : if ( GT_16( k, tmp ) )
1364 : {
1365 17 : k = tmp;
1366 17 : move16();
1367 : }
1368 :
1369 442 : low = sub( peak_cand_idx[pindx], 2 );
1370 442 : high = add( peak_cand_idx[pindx], 2 );
1371 :
1372 442 : if ( low < 0 )
1373 : {
1374 0 : low = 0;
1375 0 : move16();
1376 : }
1377 :
1378 442 : tmp = sub( N, 1 );
1379 442 : IF( GT_16( high, tmp ) )
1380 : {
1381 0 : high = tmp;
1382 0 : move16();
1383 : }
1384 :
1385 1738 : FOR( q = j; q <= pindx; q++ )
1386 : {
1387 1296 : IF( GE_16( peak_cand_idx[q], low ) )
1388 : {
1389 649 : peak_cand_idx[q] = 0;
1390 649 : move16();
1391 649 : L_input_abs[q] = 0;
1392 649 : move16();
1393 : }
1394 : }
1395 :
1396 1299 : FOR( q = pindx + 1; q <= k; q++ )
1397 : {
1398 857 : IF( LE_16( peak_cand_idx[q], high ) )
1399 : {
1400 529 : peak_cand_idx[q] = 0;
1401 529 : move16();
1402 529 : L_input_abs[q] = 0;
1403 529 : move16();
1404 : }
1405 : }
1406 :
1407 442 : pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m ); /* Q0 */
1408 : }
1409 :
1410 19 : *Npeaks = i;
1411 19 : move16();
1412 19 : IF( GT_16( *Npeaks, HVQ_MIN_PEAKS ) )
1413 : {
1414 19 : test();
1415 19 : IF( GT_16( num_sharp_bands, sub( nsub, 3 ) ) && LE_16( *Npeaks, peak_th ) )
1416 : {
1417 0 : sharp_dist = mult( sharp_dist, inv_nsub ); /*x+15-15=x */
1418 0 : test();
1419 0 : IF( LE_16( sharp_dist, SHARP_DIST_THRES_FX ) && *hvq_hangover < 0 )
1420 : {
1421 0 : *hvq_hangover = add( *hvq_hangover, 1 );
1422 : }
1423 : ELSE
1424 : {
1425 0 : *hqswb_clas = HQ_HVQ; /* Q0 */
1426 0 : move16();
1427 0 : *hvq_hangover = 2; /* Q0 */
1428 0 : move16();
1429 : }
1430 :
1431 : /* update memory */
1432 0 : *prev_Npeaks = *Npeaks; /* Q0 */
1433 0 : move16();
1434 0 : Copy( peaks, prev_peaks, *Npeaks ); /* Q0 */
1435 : }
1436 : ELSE
1437 : {
1438 19 : IF( *hvq_hangover > 0 )
1439 : {
1440 0 : *hqswb_clas = HQ_HVQ; /* Q0 */
1441 0 : move16();
1442 0 : *hvq_hangover = sub( *hvq_hangover, 1 ); /* Q0 */
1443 0 : move16();
1444 : }
1445 : ELSE
1446 : {
1447 19 : *hvq_hangover = -1;
1448 19 : move16();
1449 : }
1450 : }
1451 : }
1452 : ELSE
1453 : {
1454 : /* Zero peaks, likely silence input. */
1455 0 : *hvq_hangover = -1;
1456 0 : move16();
1457 : }
1458 :
1459 19 : IF( EQ_32( L_core_brate, HQ_24k40 ) )
1460 : {
1461 19 : *Npeaks = s_min( HVQ_MAX_PEAKS_24k, *Npeaks ); /* Q0 */
1462 19 : move16();
1463 : }
1464 : ELSE
1465 : {
1466 0 : *Npeaks = s_min( HVQ_MAX_PEAKS_32k, *Npeaks ); /* Q0 */
1467 0 : move16();
1468 : }
1469 : }
1470 : ELSE
1471 : {
1472 47 : *prev_Npeaks = 0;
1473 47 : move16();
1474 47 : *hvq_hangover = 0;
1475 47 : move16();
1476 : }
1477 :
1478 :
1479 66 : return;
1480 : }
|