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 6674 : 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 6674 : Word16 inv_rms32_e = 0;
64 6674 : move16();
65 :
66 6674 : crest_lp_fx = &st->hHQ_core->crest_lp_fx; /* &st->hHQ_core->crest_lp_q */
67 6674 : crest_mod_lp_fx = &st->hHQ_core->crest_mod_lp_fx; /* &st->hHQ_core->crest_mod_lp_q */
68 :
69 6674 : result = TRUE;
70 6674 : move16();
71 6674 : IF( st->element_mode != EVS_MONO )
72 : {
73 :
74 2142354 : FOR( i = 0; i < L_SPEC_HB; i++ )
75 : {
76 2135680 : A_fx[i] = L_abs( coefs_fx[i + L_SPEC_HB] ); /* Q12 */
77 2135680 : move32();
78 : }
79 6674 : low_count_fx = 0;
80 6674 : move16();
81 6674 : inv_rms_fx = 0;
82 6674 : move64();
83 6674 : crest_mod_fx = 0;
84 6674 : move32();
85 6674 : maximum_l( A_fx, L_SPEC_HB, &Amax_fx );
86 6674 : 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 6674 : thr_fx = Mpy_32_32( Amax_fx, PEAK_THRESHOLD_FX ); /* Q12 */
97 6674 : movmean_fx = 0; /* avoid uninitialized warning */
98 6674 : move32();
99 : // p_num = &inv_tbl[HALF_WIN_LENGTH + 1]; /* Table for division 1./(11:21) */
100 6674 : p_num_fx = &inv_tbl_fx[HALF_WIN_LENGTH + 1]; /* Table for division 1./(11:21) Q15*/
101 2142354 : FOR( i = 0; i < L_SPEC_HB; i++ )
102 : {
103 : // inv_rms += A[i] * A[i];
104 2135680 : 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 2135680 : IF( LT_32( A_fx[i], thr_fx ) )
107 : {
108 1355915 : low_count_fx = add( low_count_fx, 1 );
109 : }
110 2135680 : IF( LE_16( i, HALF_WIN_LENGTH ) )
111 : {
112 73414 : IF( i == 0 )
113 : {
114 6674 : 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 66740 : p_num_fx++;
120 66740 : 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 2062266 : IF( LE_16( L_SPEC_HB, i + HALF_WIN_LENGTH ) )
126 : {
127 :
128 66740 : p_num_fx--;
129 66740 : 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 1995526 : 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 2135680 : IF( LT_32( crest_mod_fx, movmean_fx ) )
138 : {
139 88797 : crest_mod_fx = movmean_fx; // Q12
140 88797 : move32();
141 : }
142 : }
143 6674 : Word16 l_shift = W_norm( inv_rms_fx );
144 6674 : inv_rms32_fx = W_extract_h( W_shl( inv_rms_fx, l_shift ) ); // Q15+l_shift-32
145 6674 : Word16 q_rms = sub( add( Q15, l_shift ), 32 ); // q_rms
146 6674 : inv_rms32_div_fx = BASOP_Util_Divide3232_Scale_newton( inv_rms32_fx, L_SPEC_HB, &inv_rms32_e ); /* Q31-inv_rms32_e */
147 6674 : 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 6674 : inv_rms32_fx = ISqrt32( inv_rms32_div_fx, &inv_rms32_e ); /* Q31-inv_rms32_e */
150 :
151 6674 : crest_fx = Mpy_32_32( Amax_fx, inv_rms32_fx ); // Q12 + (Q31-inv_rms32_e) -Q31 = Q12 - inv_rms32_e
152 6674 : crest_mod_fx = Mpy_32_32( crest_mod_fx, inv_rms32_fx ); // Q12 + (Q31-inv_rms32_e) -Q31 = Q12 - inv_rms32_e
153 6674 : *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 6674 : move32();
155 6674 : st->hHQ_core->crest_lp_q = sub( Q12, inv_rms32_e );
156 6674 : move16();
157 6674 : *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 6674 : move32();
159 6674 : st->hHQ_core->crest_mod_lp_q = sub( Q12, inv_rms32_e );
160 6674 : move16();
161 : }
162 6674 : *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 6674 : move32();
164 6674 : *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 6674 : move32();
166 :
167 6674 : 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 6674 : 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 6674 : test();
170 6674 : test();
171 6674 : 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 6674 : return result; /* Q0 */
179 : }
180 : /*--------------------------------------------------------------------------*
181 : * hq_classifier_enc_fx()
182 : *
183 : * HQ mode selector (decision_matrix)
184 : *--------------------------------------------------------------------------*/
185 370 : 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 370 : HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core;
199 :
200 370 : *hqswb_clas = HQ_NORMAL;
201 370 : 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 370 : test();
209 370 : test();
210 370 : test();
211 370 : 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 44 : *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 44 : move16();
216 :
217 : /* Detect harmonic VQ mode HQ_HVQ */
218 44 : 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 370 : test();
223 370 : test();
224 370 : test();
225 370 : 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 370 : test();
236 370 : test();
237 370 : 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 370 : test();
244 370 : IF( GE_16( length, L_FRAME32k ) && LE_32( st_fx->core_brate, HQ_32k ) )
245 : {
246 44 : bits = 2;
247 44 : move16();
248 : }
249 : ELSE
250 : {
251 326 : bits = 1;
252 326 : move16();
253 : }
254 :
255 370 : test();
256 370 : 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 370 : push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits );
270 : }
271 :
272 370 : test();
273 370 : test();
274 370 : IF( EQ_16( *hqswb_clas, HQ_NORMAL ) && EQ_16( length, L_FRAME32k ) && LE_32( st_fx->core_brate, HQ_32k ) )
275 : {
276 32 : *hqswb_clas = HQ_GEN_SWB; /* Q0 */
277 32 : move16();
278 : }
279 :
280 370 : return bits;
281 : }
282 7772 : 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 7772 : HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core;
298 : Word32 max_brate;
299 : Word16 harmonic_decision;
300 :
301 :
302 7772 : max_brate = HQ_32k;
303 7772 : move32();
304 :
305 7772 : if ( st_fx->element_mode > EVS_MONO )
306 : {
307 7772 : max_brate = HQ_48k;
308 7772 : move32();
309 : }
310 :
311 7772 : *hqswb_clas = HQ_NORMAL; /* Q0 */
312 7772 : bits = 1;
313 7772 : move16();
314 7772 : IF( EQ_16( is_transient, 1 ) )
315 : {
316 458 : *hqswb_clas = HQ_TRANSIENT; /* Q0 */
317 458 : move16();
318 : }
319 :
320 : /* classification and limit bandwidth for bit allocation */
321 7772 : test();
322 7772 : IF( EQ_16( length, L_SPEC32k ) || EQ_16( length, L_SPEC48k ) )
323 : {
324 7132 : IF( LE_32( st_fx->core_brate, max_brate ) )
325 : {
326 7132 : test();
327 7132 : IF( !is_transient && EQ_16( st_fx->bwidth, st_fx->last_bwidth ) )
328 : {
329 : /* Detect HQ_HARMONIC mode */
330 6674 : *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 6674 : harmonic_decision = hf_spectrum_sparseness_fx( st_fx, coefs );
333 :
334 :
335 6674 : test();
336 6674 : 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 6674 : 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 7132 : bits = 2;
348 7132 : move16();
349 : }
350 : }
351 640 : 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 7772 : push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits );
358 :
359 7772 : IF( LE_32( st_fx->core_brate, HQ_32k ) && EQ_16( *hqswb_clas, HQ_NORMAL ) )
360 : {
361 3272 : IF( EQ_16( length, L_SPEC32k ) )
362 : {
363 597 : *hqswb_clas = HQ_GEN_SWB; /* Q0 */
364 597 : move16();
365 : }
366 2675 : ELSE IF( EQ_16( length, L_SPEC48k ) )
367 : {
368 2210 : *hqswb_clas = HQ_GEN_FB; /* Q0 */
369 2210 : move16();
370 : }
371 : }
372 :
373 7772 : 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 6674 : 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 3637330 : FOR( i = 96; i < length; i++ )
394 : {
395 3630656 : input_abs_fx[i] = L_abs( input_hi_fx[i] );
396 3630656 : move32();
397 : }
398 :
399 6674 : hqswb_clas = HQ_NORMAL;
400 6674 : move16();
401 6674 : peak_th_fx = L_shl( 10L, sub( Q_coeff, 5 ) ); /* 5 is safe shift */
402 :
403 6674 : k = 0;
404 6674 : move16();
405 6674 : k1 = 0;
406 6674 : move16();
407 6674 : q = 96; /* q used for indexing */
408 6674 : move16();
409 :
410 100110 : FOR( i = 3; i < 17; i++ )
411 : {
412 93436 : peak_fx = L_deposit_l( 0 );
413 93436 : mean_fx = L_deposit_l( 1 );
414 :
415 : /*for(j = 0; j < 32; j ++, q ++) */
416 3083388 : FOR( j = 0; j < 32; j++ )
417 : {
418 2989952 : input_abs_fx[q] = L_shr( input_abs_fx[q], 5 ); /*Q_coeff-5 */
419 2989952 : move32();
420 2989952 : mean_fx = L_add( mean_fx, input_abs_fx[q] ); /*Q_coeff-5 */
421 2989952 : if ( GT_32( input_abs_fx[q], peak_fx ) )
422 : {
423 412875 : peak_fx = input_abs_fx[q]; /*Q_coeff-5 */
424 412875 : move32();
425 : }
426 2989952 : q += 1;
427 : }
428 :
429 93436 : IF( LT_16( i, 8 ) )
430 : {
431 33370 : if ( GT_32( peak_fx, Mult_32_16( mean_fx, 4608 ) ) ) /* Q15 0.140625 */
432 : {
433 22340 : k = add( k, 1 );
434 : }
435 : }
436 : ELSE
437 : {
438 60066 : test();
439 60066 : if ( GT_32( peak_fx, Mult_32_16( mean_fx, 3686 ) ) /*Q15 0.1125 */
440 25720 : && GT_32( peak_fx, peak_th_fx ) ) /*Q27 10 */
441 : {
442 22257 : k1 = add( k1, 1 );
443 : }
444 : }
445 : }
446 :
447 6674 : test();
448 6674 : IF( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) )
449 : {
450 1690 : IF( LT_16( *mode_count, 8 ) )
451 : {
452 1690 : *mode_count = add( *mode_count, 1 );
453 1690 : move16();
454 : }
455 :
456 1690 : IF( *mode_count1 > 0 )
457 : {
458 0 : *mode_count1 = sub( *mode_count1, 1 );
459 0 : move16();
460 : }
461 : }
462 : ELSE
463 : {
464 4984 : IF( LT_16( *mode_count1, 8 ) )
465 : {
466 4984 : *mode_count1 = add( *mode_count1, 1 );
467 4984 : move16();
468 : }
469 :
470 4984 : IF( *mode_count > 0 )
471 : {
472 0 : *mode_count = sub( *mode_count, 1 );
473 0 : move16();
474 : }
475 : }
476 :
477 6674 : test();
478 6674 : test();
479 6674 : test();
480 6674 : test();
481 6674 : test();
482 6674 : test();
483 :
484 6674 : 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 2245 : hqswb_clas = HQ_HARMONIC;
487 2245 : move16();
488 : }
489 6674 : 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 80 : 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 40144 : FOR( i = 96; i < length; i++ )
510 : {
511 40064 : input_abs_fx[i] = L_abs( input_hi_fx[i] ); /* Q_coeff */
512 : }
513 :
514 80 : hqswb_clas = HQ_NORMAL;
515 80 : move16();
516 80 : peak_th_fx = L_shl( 10L, sub( Q_coeff, 5 ) ); /* 5 is safe shift */
517 :
518 80 : k = 0;
519 80 : move16();
520 80 : k1 = 0;
521 80 : move16();
522 80 : q = 96; /* q used for indexing */
523 80 : move16();
524 :
525 1200 : FOR( i = 3; i < 17; i++ )
526 : {
527 1120 : peak_fx = L_deposit_l( 0 );
528 1120 : mean_fx = L_deposit_l( 1 );
529 :
530 : /*for(j = 0; j < 32; j ++, q ++) */
531 36960 : FOR( j = 0; j < 32; j++ )
532 : {
533 35840 : input_abs_fx[q] = L_shr( input_abs_fx[q], 5 ); /*Q_coeff-5 */
534 35840 : move32();
535 35840 : mean_fx = L_add( mean_fx, input_abs_fx[q] ); /*Q_coeff-5 */
536 35840 : if ( GT_32( input_abs_fx[q], peak_fx ) )
537 : {
538 4648 : peak_fx = input_abs_fx[q]; /*Q_coeff-5 */
539 4648 : move32();
540 : }
541 35840 : q += 1;
542 : }
543 :
544 1120 : IF( LT_16( i, 8 ) )
545 : {
546 400 : if ( GT_32( peak_fx, Mult_32_16( mean_fx, 4608 ) ) ) /* Q15 0.140625 */
547 : {
548 82 : k = add( k, 1 );
549 : }
550 : }
551 : ELSE
552 : {
553 720 : test();
554 720 : if ( GT_32( peak_fx, Mult_32_16( mean_fx, 3686 ) ) /*Q15 0.1125 */
555 186 : && GT_32( peak_fx, peak_th_fx ) ) /*Q27 10 */
556 : {
557 170 : k1 = add( k1, 1 );
558 : }
559 : }
560 : }
561 :
562 80 : test();
563 80 : 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 80 : IF( LT_16( *mode_count1, 8 ) )
580 : {
581 66 : *mode_count1 = add( *mode_count1, 1 );
582 66 : move16();
583 : }
584 :
585 80 : IF( *mode_count > 0 )
586 : {
587 0 : *mode_count = sub( *mode_count, 1 );
588 0 : move16();
589 : }
590 : }
591 :
592 80 : test();
593 80 : test();
594 80 : test();
595 80 : test();
596 80 : test();
597 80 : test();
598 :
599 80 : 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 12 : hqswb_clas = HQ_HARMONIC;
602 12 : move16();
603 : }
604 :
605 80 : return hqswb_clas; /* Q0 */
606 : }
607 :
608 : /*--------------------------------------------------------------------------*
609 : * hvq_classifier()
610 : *
611 : * Classification of harmonic low band content for Harmonic VQ
612 : *--------------------------------------------------------------------------*/
613 6674 : 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 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
656 6674 : Flag Overflow = 0;
657 6674 : move16();
658 : #endif
659 6674 : Word16 temp_e = 0;
660 6674 : move16();
661 6674 : L_input_max = L_deposit_l( 0 );
662 6674 : set32_fx( L_thr, 0, L_FRAME16k );
663 :
664 6674 : IF( LT_32( L_core_brate, HQ_BWE_CROSSOVER_BRATE ) )
665 : {
666 2641 : nsub = HVQ_NSUB_24k;
667 2641 : move16();
668 2641 : inv_nsub = 4681; /* 1/7 in Q15 */
669 2641 : move16();
670 2641 : inv_gains_nsub = 10923; /* 1/3 in Q15 */
671 2641 : move16();
672 : }
673 : ELSE
674 : {
675 4033 : nsub = HVQ_NSUB_32k;
676 4033 : move16();
677 4033 : inv_nsub = 3277; /* 1/10 in Q15 */
678 4033 : move16();
679 4033 : inv_gains_nsub = 6554; /* 1/5 in Q15 */
680 4033 : move16();
681 : }
682 :
683 6674 : N = shl( nsub, 5 ); /* Mult by 32 (HVQ_BW) */
684 :
685 6674 : test();
686 6674 : test();
687 6674 : IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && last_core != ACELP_CORE && NE_16( last_core, AMR_WB_CORE ) )
688 2215 : {
689 594375 : FOR( i = 0; i < N; i++ )
690 : {
691 592160 : L_input_abs[i] = L_abs( input[i] ); /* Q12 */
692 592160 : move16();
693 592160 : IF( GT_32( L_input_abs[i], L_input_max ) )
694 : {
695 13497 : L_input_max = L_input_abs[i]; /* Q12 */
696 13497 : move16();
697 : }
698 : }
699 :
700 2215 : exp1 = norm_l( L_input_max );
701 :
702 2215 : *Npeaks = 0;
703 2215 : move16();
704 2215 : L_nf = 3276800; /* 800 in Q12 */
705 2215 : move32();
706 2215 : L_pe = 3276800; /* 800 in Q12 */
707 2215 : move32();
708 2215 : num_sharp_bands = 0;
709 2215 : move16();
710 2215 : k = 0;
711 2215 : move16();
712 2215 : q = 0;
713 2215 : move16();
714 2215 : sharp_dist = 0;
715 2215 : move16();
716 :
717 : /* Find peak threshold */
718 20720 : FOR( i = 0; i < nsub; i++ )
719 : {
720 18505 : L_peak = 0;
721 18505 : L_nf_mean[i] = 0;
722 18505 : L_pe_mean[i] = 0;
723 18505 : move32();
724 18505 : move32();
725 18505 : move32();
726 :
727 610665 : FOR( j = 0; j < HVQ_BW; j++ )
728 : {
729 592160 : L_d = L_input_abs[q]; /* Q12 */
730 592160 : IF( GT_32( L_d, L_nf ) )
731 : {
732 : /*nf = HVQ_NF_WEIGHT1 * nf + (1 - HVQ_NF_WEIGHT1) * d; */
733 316205 : Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT1B, &L_tmp, &lsb ); /* 12+15-15=12 */
734 316205 : Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT1_FX, &L_nf, &lsb ); /* 12+15-15=12 */
735 316205 : L_nf = L_add( L_nf, L_tmp ); /*Q12 */
736 : }
737 : ELSE
738 : {
739 : /*nf = HVQ_NF_WEIGHT2 * nf + (1 - HVQ_NF_WEIGHT2) * d; */
740 275955 : Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT2B, &L_tmp, &lsb ); /* 12+15-15=12 */
741 275955 : Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT2_FX, &L_nf, &lsb ); /* 12+15-15=12 */
742 275955 : L_nf = L_add( L_nf, L_tmp ); /*Q12 */
743 : }
744 :
745 592160 : IF( GT_32( L_d, L_pe ) )
746 : {
747 : /*pe = HVQ_PE_WEIGHT1 * pe + (1 - HVQ_PE_WEIGHT1) * d; */
748 118293 : Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT1B, &L_tmp, &lsb ); /* 12+15-15=12 */
749 118293 : Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT1_FX, &L_pe, &lsb ); /* 12+15-15=12 */
750 118293 : L_pe = L_add( L_pe, L_tmp ); /*Q12 */
751 : }
752 : ELSE
753 : {
754 : /*pe = HVQ_PE_WEIGHT2 * pe + (1 - HVQ_PE_WEIGHT2) * d; */
755 473867 : Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT2B, &L_tmp, &lsb ); /* 12+15-15=12 */
756 473867 : Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT2_FX, &L_pe, &lsb ); /* 12+15-15=12 */
757 473867 : L_pe = L_add( L_pe, L_tmp ); /*Q12 */
758 : }
759 :
760 592160 : L_nf_mean[i] = L_add_sat( L_nf_mean[i], L_nf ); /*Q12 */
761 592160 : L_pe_mean[i] = L_add_sat( L_pe_mean[i], L_pe ); /*Q12 */
762 592160 : move32();
763 592160 : move32();
764 592160 : IF( GT_32( L_d, L_peak ) )
765 : {
766 88825 : L_peak = L_add( L_d, 0 );
767 : }
768 :
769 592160 : q += 1;
770 : }
771 18505 : L_nf_mean[i] = L_shr( L_nf_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
772 18505 : L_pe_mean[i] = L_shr( L_pe_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
773 18505 : move32();
774 18505 : move32();
775 : /*thr_tmp = (float)pow( pe_mean[i]/nf_mean[i], HVQ_THR_POW ) * nf_mean[i]; */
776 18505 : exp1 = norm_l( L_nf_mean[i] );
777 18505 : nf_mean_norm = extract_h( L_shl( L_nf_mean[i], exp1 ) ); /* 12+s-16=s-4 */
778 18505 : IF( nf_mean_norm == 0 )
779 : {
780 0 : inv_nf_mean = 0;
781 : }
782 : ELSE
783 : {
784 18505 : inv_nf_mean = div_s( 1 << 14, nf_mean_norm ); /* 15+14-s+4=33-s */
785 : }
786 18505 : Mpy_32_16_ss( L_pe_mean[i], inv_nf_mean, &L_tmp, &lsb ); /*12+33-s-15=30-s */
787 :
788 18505 : exp2 = norm_l( L_tmp );
789 18505 : tmp = Log2_norm_lc( L_shl( L_tmp, exp2 ) ); /* Q15 */
790 18505 : exp2 = sub( exp1, exp2 ); /* Q0 */
791 18505 : L_tmp = Mpy_32_16( exp2, tmp, 32767 ); /* 1 in Q15. Q16 */
792 18505 : Mpy_32_16_ss( L_tmp, 28836, &L_tmp, &lsb ); /* 16+15-15=16 */
793 18505 : frac = L_Extract_lc( L_tmp, &tmp ); /* Q15 and Q0 */
794 18505 : L_tmp = Pow2( 14, frac ); /* Q14 */
795 18505 : L_tmp = L_shl( L_tmp, tmp ); /* Q14 */
796 :
797 18505 : Mpy_32_16_ss( L_tmp, nf_mean_norm, &L_tmp, &lsb ); /*14+s-4-15=s-5 */
798 18505 : shift = sub( 17, exp1 ); /* 16-(s-5)=17-s */
799 18505 : L_thr_tmp = L_shl( L_tmp, shift ); /* Q16 */
800 18505 : L_thr_tmp = L_add( L_thr_tmp, lshr( lsb, sub( 16, shift ) ) ); /*Q16 */
801 :
802 18505 : set32_fx( &L_thr[k], L_thr_tmp, HVQ_BW );
803 18505 : k = add( k, HVQ_BW );
804 :
805 : /*sharp[i] = peak/nf_mean[i]; */
806 18505 : Mpy_32_16_ss( L_peak, inv_nf_mean, &L_tmp, &lsb ); /* 12+33-s-15=30-s */
807 18505 : shift = sub( exp1, 8 );
808 18505 : sharp[i] = extract_h( L_shl( L_tmp, shift ) ); /* 30-s+s-8-16 -> Q6 */
809 18505 : move16();
810 : /*sharp_dist += (sharp[i]-HVQ_SHARP_THRES); */
811 18505 : sharp_dist = add_o( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ), &Overflow ); /* Q6 */
812 18505 : if ( GT_16( sharp[i], HVQ_SHARP_THRES_FX ) )
813 : {
814 15934 : num_sharp_bands = add( num_sharp_bands, 1 );
815 : }
816 : }
817 :
818 : /* Estimate noise floor gains */
819 2215 : offset = s_and( nsub, 1 );
820 19505 : FOR( i = 0; i < ( nsub & (Word16) 0xFFFE ); i++ )
821 : {
822 : /*(2*i+1)/nsub */
823 17290 : idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */
824 17290 : L_nf_gains[idx] = L_add( L_nf_gains[idx], L_nf_mean[i + offset] ); /* Q12 */
825 17290 : L_pe_gains[idx] = L_add( L_pe_gains[idx], L_pe_mean[i + offset] ); /* Q12 */
826 17290 : move32();
827 17290 : move32();
828 : }
829 :
830 6645 : FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
831 : {
832 4430 : Mpy_32_16_ss( L_nf_gains[i], inv_gains_nsub, &L_nf_gains[i], &lsb ); /*12+15-15=12 */
833 4430 : Mpy_32_16_ss( L_pe_gains[i], inv_gains_nsub, &L_pe_gains[i], &lsb ); /*12+15-15=12 */
834 : }
835 :
836 : /* Allocate available peaks */
837 20720 : FOR( i = 0; i < nsub; i++ )
838 : {
839 18505 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP1; /* Q0 */
840 18505 : move16();
841 18505 : idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */
842 18505 : Mpy_32_16_ss( L_nf_gains[idx], HVQ_PA_FAC_FX, &L_tmp, &lsb ); /* 12+15-15 -> Q12 */
843 18505 : IF( LT_32( L_nf_mean[i], L_tmp ) )
844 : {
845 6678 : IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES3_FX ) )
846 : {
847 1487 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP3; /* Q0 */
848 1487 : move16();
849 : }
850 5191 : ELSE IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES2_FX ) )
851 : {
852 673 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP2; /* Q0 */
853 673 : move16();
854 : }
855 : }
856 : }
857 :
858 :
859 : /* Adjust threshold around previous peaks */
860 27033 : FOR( i = 0; i < *prev_Npeaks; i++ )
861 : {
862 24818 : j = sub( prev_peaks[i], 2 ); /* Q0 */
863 24818 : k = add( prev_peaks[i], 2 ); /* Q0 */
864 24818 : p_adj = hvq_thr_adj_fx; /* Q15 */
865 :
866 124090 : FOR( q = j; q < k; q++ )
867 : {
868 99272 : Mpy_32_16_ss( L_thr[q], *p_adj++, &L_thr[q], &lsb ); /* 12+15-15=12 */
869 99272 : move32();
870 : }
871 : }
872 :
873 2215 : num_peak_cands = 0;
874 2215 : move16();
875 :
876 : /* Remove everything below threshold for peak search */
877 2215 : L_input_abs[0] = L_deposit_l( 0 );
878 2215 : L_input_abs[1] = L_deposit_l( 0 );
879 2215 : L_input_abs[N - 2] = L_deposit_l( 0 );
880 2215 : L_input_abs[N - 1] = L_deposit_l( 0 );
881 2215 : move32();
882 2215 : move32();
883 2215 : move32();
884 2215 : move32();
885 589945 : FOR( i = 0; i < N - 2; i++ )
886 : {
887 587730 : IF( LT_32( L_input_abs[i], L_thr[i] ) )
888 : {
889 479653 : L_input_abs[i] = L_deposit_l( 0 );
890 :
891 479653 : move32();
892 : }
893 : ELSE
894 : {
895 108077 : L_input_abs[num_peak_cands] = L_input_abs[i]; /* Q12 */
896 108077 : move32();
897 108077 : peak_cand_idx[num_peak_cands] = i; /* Q0 */
898 108077 : move16();
899 108077 : num_peak_cands = add( num_peak_cands, 1 );
900 : }
901 : }
902 :
903 :
904 2215 : 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 ) );
905 2215 : peak_th = shr( peak_th, sub( 15, temp_e ) );
906 : /* Find peaks */
907 2215 : pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
908 2215 : i = 0;
909 2215 : move16();
910 :
911 46418 : WHILE( L_m > 0 && LT_16( i, peak_th + 1 ) )
912 : {
913 44203 : idx = mult( peak_cand_idx[pindx], INV_HVQ_BW ); /* 0+15-15=0 */
914 44203 : IF( avail_peaks[idx] > 0 )
915 : {
916 43189 : peaks[i++] = peak_cand_idx[pindx]; /* Q0 */
917 43189 : avail_peaks[idx]--;
918 : }
919 :
920 44203 : j = sub( pindx, 2 );
921 44203 : k = add( pindx, 2 );
922 :
923 44203 : if ( j < 0 )
924 : {
925 2149 : j = 0;
926 2149 : move16();
927 : }
928 :
929 44203 : tmp = sub( num_peak_cands, 1 );
930 44203 : if ( GT_16( k, tmp ) )
931 : {
932 1553 : k = tmp;
933 1553 : move16();
934 : }
935 :
936 44203 : low = sub( peak_cand_idx[pindx], 2 );
937 44203 : high = add( peak_cand_idx[pindx], 2 );
938 :
939 44203 : if ( low < 0 )
940 : {
941 0 : low = 0;
942 0 : move16();
943 : }
944 :
945 44203 : tmp = sub( N, 1 );
946 44203 : if ( GT_16( high, tmp ) )
947 : {
948 0 : high = tmp;
949 0 : move16();
950 : }
951 :
952 173373 : FOR( q = j; q <= pindx; q++ )
953 : {
954 129170 : IF( GE_16( peak_cand_idx[q], low ) )
955 : {
956 73041 : peak_cand_idx[q] = 0;
957 73041 : move16();
958 73041 : L_input_abs[q] = 0;
959 73041 : move16();
960 : }
961 : }
962 :
963 130247 : FOR( q = pindx + 1; q <= k; q++ )
964 : {
965 86044 : IF( LE_16( peak_cand_idx[q], high ) )
966 : {
967 59182 : peak_cand_idx[q] = 0;
968 59182 : move16();
969 59182 : L_input_abs[q] = 0;
970 59182 : move16();
971 : }
972 : }
973 :
974 44203 : pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
975 : }
976 :
977 2215 : *Npeaks = i; /* Q0 */
978 2215 : move16();
979 2215 : IF( GT_16( *Npeaks, HVQ_MIN_PEAKS ) )
980 : {
981 2215 : test();
982 2215 : IF( GT_16( num_sharp_bands, sub( nsub, 3 ) ) && LE_16( *Npeaks, peak_th ) )
983 : {
984 1231 : sharp_dist = mult( sharp_dist, inv_nsub ); /*x+15-15=x */
985 1231 : test();
986 1231 : IF( LE_16( sharp_dist, SHARP_DIST_THRES_FX ) && *hvq_hangover < 0 )
987 : {
988 39 : *hvq_hangover = add( *hvq_hangover, 1 ); /* Q0 */
989 : }
990 : ELSE
991 : {
992 1192 : *hqswb_clas = HQ_HVQ; /* Q0 */
993 1192 : move16();
994 1192 : *hvq_hangover = 2; /* Q0 */
995 1192 : move16();
996 : }
997 :
998 : /* update memory */
999 1231 : *prev_Npeaks = *Npeaks; /* Q0 */
1000 1231 : move16();
1001 1231 : Copy( peaks, prev_peaks, *Npeaks ); /* Q0 */
1002 : }
1003 : ELSE
1004 : {
1005 984 : IF( *hvq_hangover > 0 )
1006 : {
1007 274 : *hqswb_clas = HQ_HVQ; /* Q0 */
1008 274 : move16();
1009 274 : *hvq_hangover = sub( *hvq_hangover, 1 ); /* Q0 */
1010 274 : move16();
1011 : }
1012 : ELSE
1013 : {
1014 710 : *hvq_hangover = -1;
1015 710 : move16();
1016 : }
1017 : }
1018 : }
1019 : ELSE
1020 : {
1021 : /* Zero peaks, likely silence input. */
1022 0 : *hvq_hangover = -1;
1023 0 : move16();
1024 : }
1025 :
1026 : //*Npeaks = (int16_t) ( s_min( ( L_core_brate * HVQ_PEAKS_PER_DELTA + HVQ_PEAKS_PER_DELTA_OFFS ) / HVQ_PEAKS_BPS_DELTA, *Npeaks ) );
1027 2215 : temp_e = 0;
1028 2215 : move16();
1029 2215 : Word16 Npeaks_temp = *Npeaks;
1030 2215 : *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 );
1031 2215 : *Npeaks = s_min( shr( *Npeaks, sub( 15, temp_e ) ), Npeaks_temp );
1032 2215 : move16();
1033 : }
1034 : ELSE
1035 : {
1036 4459 : *prev_Npeaks = 0;
1037 4459 : move16();
1038 4459 : *hvq_hangover = 0;
1039 4459 : move16();
1040 : }
1041 :
1042 :
1043 6674 : return;
1044 : }
1045 :
1046 44 : void hvq_classifier_fx(
1047 : const Word32 *input, /* i : input signal Q12 */
1048 : Word16 *prev_Npeaks, /* i/o: Peak number memory Q0 */
1049 : Word16 *prev_peaks, /* i/o: Peak indices memory Q0 */
1050 : Word16 *hqswb_clas, /* i/o: HQ class Q0 */
1051 : Word16 *Npeaks, /* o : Number of peaks Q0 */
1052 : Word16 *peaks, /* o : Peak indices Q0 */
1053 : const Word32 L_core_brate, /* i : Core bit-rate Q0 */
1054 : const Word16 last_core, /* i : Last core used Q0 */
1055 : Word32 *L_nf_gains, /* o : Noisefloor gains Q12 */
1056 : Word16 *hvq_hangover, /* i/o: Mode-switch hangover Q0 */
1057 : Word32 *L_pe_gains /* o : peak gains Q12 */
1058 : )
1059 : {
1060 : const Word16 *p_adj;
1061 : UWord16 lsb;
1062 :
1063 : Word32 L_input_abs[L_FRAME32k];
1064 : Word32 L_input_max;
1065 : Word32 L_thr[L_FRAME16k];
1066 : Word32 L_thr_tmp;
1067 : Word32 L_m;
1068 : Word32 L_tmp;
1069 : Word32 L_d;
1070 : Word32 L_peak;
1071 : Word32 L_nf, L_pe;
1072 : Word32 L_pe_mean[HVQ_NSUB_32k], L_nf_mean[HVQ_NSUB_32k];
1073 :
1074 : Word16 inv_nsub;
1075 : Word16 sharp_dist;
1076 : Word16 exp1, exp2;
1077 : Word16 tmp;
1078 : Word16 shift;
1079 : Word16 idx;
1080 : Word16 frac;
1081 : Word16 inv_nf_mean;
1082 : Word16 inv_gains_nsub;
1083 : Word16 nf_mean_norm;
1084 : Word16 num_sharp_bands, i, j, k, q, peak_th, nsub, pindx, N, offset;
1085 : Word16 num_peak_cands, high, low;
1086 : Word16 sharp[HVQ_NSUB_32k];
1087 : Word16 peak_cand_idx[HVQ_THRES_BIN_32k], avail_peaks[HVQ_NSUB_32k];
1088 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1089 44 : Flag Overflow = 0;
1090 44 : move32();
1091 : #endif
1092 44 : L_input_max = L_deposit_l( 0 );
1093 44 : set32_fx( L_thr, 0, L_FRAME16k );
1094 :
1095 44 : IF( EQ_32( L_core_brate, HQ_24k40 ) )
1096 : {
1097 44 : nsub = HVQ_NSUB_24k;
1098 44 : move16();
1099 44 : inv_nsub = 4681; /* 1/7 in Q15 */
1100 44 : move16();
1101 44 : inv_gains_nsub = 10923; /* 1/3 in Q15 */
1102 44 : move16();
1103 : }
1104 : ELSE
1105 : {
1106 0 : nsub = HVQ_NSUB_32k;
1107 0 : move16();
1108 0 : inv_nsub = 3277; /* 1/10 in Q15 */
1109 0 : move16();
1110 0 : inv_gains_nsub = 6554; /* 1/5 in Q15 */
1111 0 : move16();
1112 : }
1113 :
1114 44 : N = shl( nsub, 5 ); /* Mult by 32 (HVQ_BW) */
1115 :
1116 44 : test();
1117 44 : test();
1118 44 : IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && last_core != ACELP_CORE && NE_16( last_core, AMR_WB_CORE ) )
1119 : {
1120 2700 : FOR( i = 0; i < N; i++ )
1121 : {
1122 2688 : L_input_abs[i] = L_abs( input[i] ); /* Q12 */
1123 2688 : IF( GT_32( L_input_abs[i], L_input_max ) )
1124 : {
1125 62 : L_input_max = L_input_abs[i]; /* Q12 */
1126 62 : move16();
1127 : }
1128 : }
1129 :
1130 12 : exp1 = norm_l( L_input_max );
1131 :
1132 12 : *Npeaks = 0;
1133 12 : move16();
1134 12 : L_nf = 3276800; /* 800 in Q12 */
1135 12 : move32();
1136 12 : L_pe = 3276800; /* 800 in Q12 */
1137 12 : move32();
1138 12 : num_sharp_bands = 0;
1139 12 : move16();
1140 12 : k = 0;
1141 12 : move16();
1142 12 : q = 0;
1143 12 : move16();
1144 12 : sharp_dist = 0;
1145 12 : move16();
1146 :
1147 : /* Find peak threshold */
1148 96 : FOR( i = 0; i < nsub; i++ )
1149 : {
1150 84 : L_peak = 0;
1151 84 : L_nf_mean[i] = 0;
1152 84 : L_pe_mean[i] = 0;
1153 84 : move32();
1154 84 : move32();
1155 84 : move32();
1156 2772 : FOR( j = 0; j < HVQ_BW; j++ )
1157 : {
1158 2688 : L_d = L_input_abs[q]; /* Q12 */
1159 2688 : move32();
1160 2688 : IF( GT_32( L_d, L_nf ) )
1161 : {
1162 : /*nf = HVQ_NF_WEIGHT1 * nf + (1 - HVQ_NF_WEIGHT1) * d; */
1163 1768 : Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT1B, &L_tmp, &lsb ); /* 12+15-15=12 */
1164 1768 : Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT1_FX, &L_nf, &lsb ); /* 12+15-15=12 */
1165 1768 : L_nf = L_add( L_nf, L_tmp ); /*Q12 */
1166 : }
1167 : ELSE
1168 : {
1169 : /*nf = HVQ_NF_WEIGHT2 * nf + (1 - HVQ_NF_WEIGHT2) * d; */
1170 920 : Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT2B, &L_tmp, &lsb ); /* 12+15-15=12 */
1171 920 : Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT2_FX, &L_nf, &lsb ); /* 12+15-15=12 */
1172 920 : L_nf = L_add( L_nf, L_tmp ); /*Q12 */
1173 : }
1174 :
1175 2688 : IF( GT_32( L_d, L_pe ) )
1176 : {
1177 : /*pe = HVQ_PE_WEIGHT1 * pe + (1 - HVQ_PE_WEIGHT1) * d; */
1178 704 : Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT1B, &L_tmp, &lsb ); /* 12+15-15=12 */
1179 704 : Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT1_FX, &L_pe, &lsb ); /* 12+15-15=12 */
1180 704 : L_pe = L_add( L_pe, L_tmp ); /*Q12 */
1181 : }
1182 : ELSE
1183 : {
1184 : /*pe = HVQ_PE_WEIGHT2 * pe + (1 - HVQ_PE_WEIGHT2) * d; */
1185 1984 : Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT2B, &L_tmp, &lsb ); /* 12+15-15=12 */
1186 1984 : Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT2_FX, &L_pe, &lsb ); /* 12+15-15=12 */
1187 1984 : L_pe = L_add( L_pe, L_tmp ); /*Q12 */
1188 : }
1189 :
1190 2688 : L_nf_mean[i] = L_add_sat( L_nf_mean[i], L_nf ); /*Q12 */
1191 2688 : L_pe_mean[i] = L_add_sat( L_pe_mean[i], L_pe ); /*Q12 */
1192 2688 : move32();
1193 2688 : move32();
1194 2688 : IF( GT_32( L_d, L_peak ) )
1195 : {
1196 367 : L_peak = L_add( L_d, 0 );
1197 : }
1198 :
1199 2688 : q += 1;
1200 : }
1201 84 : L_nf_mean[i] = L_shr( L_nf_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
1202 84 : L_pe_mean[i] = L_shr( L_pe_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
1203 84 : move32();
1204 84 : move32();
1205 :
1206 : /*thr_tmp = (float)pow( pe_mean[i]/nf_mean[i], HVQ_THR_POW ) * nf_mean[i]; */
1207 84 : exp1 = norm_l( L_nf_mean[i] );
1208 84 : nf_mean_norm = extract_h( L_shl( L_nf_mean[i], exp1 ) ); /* 12+s-16=s-4 */
1209 84 : IF( nf_mean_norm == 0 )
1210 : {
1211 0 : inv_nf_mean = 0;
1212 : }
1213 : ELSE
1214 : {
1215 84 : inv_nf_mean = div_s( 1 << 14, nf_mean_norm ); /* 15+14-s+4=33-s */
1216 : }
1217 84 : Mpy_32_16_ss( L_pe_mean[i], inv_nf_mean, &L_tmp, &lsb ); /*12+33-s-15=30-s */
1218 :
1219 84 : exp2 = norm_l( L_tmp );
1220 84 : tmp = Log2_norm_lc( L_shl( L_tmp, exp2 ) ); /* Q15 */
1221 84 : exp2 = exp1 - exp2; /* Q0 */
1222 84 : L_tmp = Mpy_32_16( exp2, tmp, 32767 ); /* 1 in Q15. Q16 */
1223 84 : Mpy_32_16_ss( L_tmp, 28836, &L_tmp, &lsb ); /* 16+15-15=16 */
1224 84 : frac = L_Extract_lc( L_tmp, &tmp ); /* Q15 and Q0 */
1225 84 : L_tmp = Pow2( 14, frac ); /* Q14 */
1226 84 : L_tmp = L_shl( L_tmp, tmp ); /* Q14 */
1227 :
1228 84 : Mpy_32_16_ss( L_tmp, nf_mean_norm, &L_tmp, &lsb ); /*14+s-4-15=s-5 */
1229 84 : shift = sub( 17, exp1 ); /* 16-(s-5)=17-s */
1230 84 : L_thr_tmp = L_shl( L_tmp, shift ); /* Q16 */
1231 84 : L_thr_tmp = L_add( L_thr_tmp, lshr( lsb, sub( 16, shift ) ) ); /*Q16 */
1232 :
1233 84 : set32_fx( &L_thr[k], L_thr_tmp, HVQ_BW );
1234 84 : k = add( k, HVQ_BW );
1235 :
1236 : /*sharp[i] = peak/nf_mean[i]; */
1237 84 : Mpy_32_16_ss( L_peak, inv_nf_mean, &L_tmp, &lsb ); /* 12+33-s-15=30-s */
1238 84 : shift = sub( exp1, 8 );
1239 84 : sharp[i] = extract_h( L_shl( L_tmp, shift ) ); /* 30-s+s-8-16 -> Q6 */
1240 84 : move16();
1241 :
1242 : /*sharp_dist += (sharp[i]-HVQ_SHARP_THRES); */
1243 84 : sharp_dist = add_o( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ), &Overflow );
1244 84 : IF( GT_16( sharp[i], HVQ_SHARP_THRES_FX ) )
1245 : {
1246 47 : num_sharp_bands = add( num_sharp_bands, 1 );
1247 : }
1248 : }
1249 :
1250 : /* Estimate noise floor gains */
1251 12 : offset = s_and( nsub, 1 );
1252 84 : FOR( i = 0; i < ( nsub & (Word16) 0xFFFE ); i++ )
1253 : {
1254 : /*(2*i+1)/nsub */
1255 72 : idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */
1256 72 : L_nf_gains[idx] = L_add( L_nf_gains[idx], L_nf_mean[i + offset] );
1257 72 : L_pe_gains[idx] = L_add( L_pe_gains[idx], L_pe_mean[i + offset] );
1258 72 : move32();
1259 72 : move32();
1260 : }
1261 :
1262 36 : FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
1263 : {
1264 24 : Mpy_32_16_ss( L_nf_gains[i], inv_gains_nsub, &L_nf_gains[i], &lsb ); /*12+15-15=12 */
1265 24 : Mpy_32_16_ss( L_pe_gains[i], inv_gains_nsub, &L_pe_gains[i], &lsb ); /*12+15-15=12 */
1266 : }
1267 :
1268 : /* Allocate available peaks */
1269 96 : FOR( i = 0; i < nsub; i++ )
1270 : {
1271 84 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP1;
1272 84 : move16();
1273 84 : idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */
1274 84 : Mpy_32_16_ss( L_nf_gains[idx], HVQ_PA_FAC_FX, &L_tmp, &lsb ); /* 12+15-15 -> Q12 */
1275 84 : IF( LT_32( L_nf_mean[i], L_tmp ) )
1276 : {
1277 24 : IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES3_FX ) )
1278 : {
1279 20 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP3;
1280 20 : move16();
1281 : }
1282 4 : ELSE IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES2_FX ) )
1283 : {
1284 2 : avail_peaks[i] = HVQ_PA_PEAKS_SHARP2;
1285 2 : move16();
1286 : }
1287 : }
1288 : }
1289 :
1290 :
1291 : /* Adjust threshold around previous peaks */
1292 12 : FOR( i = 0; i < *prev_Npeaks; i++ )
1293 : {
1294 0 : j = sub( prev_peaks[i], 2 ); /* Q0 */
1295 0 : k = add( prev_peaks[i], 2 ); /* Q0 */
1296 0 : p_adj = hvq_thr_adj_fx; /* Q15 */
1297 0 : move16();
1298 :
1299 0 : FOR( q = j; q < k; q++ )
1300 : {
1301 0 : Mpy_32_16_ss( L_thr[q], *p_adj++, &L_thr[q], &lsb ); /* 12+15-15=12 */
1302 0 : move32();
1303 : }
1304 : }
1305 :
1306 12 : num_peak_cands = 0;
1307 12 : move16();
1308 :
1309 : /* Remove everything below threshold for peak search */
1310 12 : L_input_abs[0] = L_deposit_l( 0 );
1311 12 : L_input_abs[1] = L_deposit_l( 0 );
1312 12 : L_input_abs[N - 2] = L_deposit_l( 0 );
1313 12 : L_input_abs[N - 1] = L_deposit_l( 0 );
1314 12 : move32();
1315 12 : move32();
1316 12 : move32();
1317 12 : move32();
1318 2676 : FOR( i = 0; i < N - 2; i++ )
1319 : {
1320 2664 : IF( LT_32( L_input_abs[i], L_thr[i] ) )
1321 : {
1322 1960 : L_input_abs[i] = L_deposit_l( 0 );
1323 1960 : move32();
1324 : }
1325 : ELSE
1326 : {
1327 704 : L_input_abs[num_peak_cands] = L_input_abs[i]; /* Q12 */
1328 704 : move32();
1329 704 : peak_cand_idx[num_peak_cands] = i; /* Q0 */
1330 704 : move16();
1331 704 : num_peak_cands = add( num_peak_cands, 1 );
1332 : }
1333 : }
1334 12 : IF( EQ_32( L_core_brate, HQ_24k40 ) )
1335 : {
1336 12 : peak_th = HVQ_MAX_PEAKS_24k_CLAS;
1337 12 : move16();
1338 : }
1339 : ELSE
1340 : {
1341 0 : peak_th = HVQ_MAX_PEAKS_32k;
1342 0 : move16();
1343 : }
1344 : /* Find peaks */
1345 12 : pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
1346 12 : i = 0;
1347 12 : move16();
1348 :
1349 300 : WHILE( L_m > 0 && LT_16( i, peak_th + 1 ) )
1350 : {
1351 288 : idx = mult( peak_cand_idx[pindx], INV_HVQ_BW ); /* 0+15-15=0 */
1352 288 : IF( avail_peaks[idx] > 0 )
1353 : {
1354 252 : peaks[i++] = peak_cand_idx[pindx]; /* Q0 */
1355 252 : move16();
1356 252 : avail_peaks[idx]--;
1357 : }
1358 :
1359 288 : j = sub( pindx, 2 );
1360 288 : k = add( pindx, 2 );
1361 :
1362 288 : if ( j < 0 )
1363 : {
1364 14 : j = 0;
1365 14 : move16();
1366 : }
1367 :
1368 288 : tmp = sub( num_peak_cands, 1 );
1369 288 : if ( GT_16( k, tmp ) )
1370 : {
1371 14 : k = tmp;
1372 14 : move16();
1373 : }
1374 :
1375 288 : low = sub( peak_cand_idx[pindx], 2 );
1376 288 : high = add( peak_cand_idx[pindx], 2 );
1377 :
1378 288 : if ( low < 0 )
1379 : {
1380 0 : low = 0;
1381 0 : move16();
1382 : }
1383 :
1384 288 : tmp = sub( N, 1 );
1385 288 : IF( GT_16( high, tmp ) )
1386 : {
1387 0 : high = tmp;
1388 0 : move16();
1389 : }
1390 :
1391 1129 : FOR( q = j; q <= pindx; q++ )
1392 : {
1393 841 : IF( GE_16( peak_cand_idx[q], low ) )
1394 : {
1395 440 : peak_cand_idx[q] = 0;
1396 440 : move16();
1397 440 : L_input_abs[q] = 0;
1398 440 : move16();
1399 : }
1400 : }
1401 :
1402 840 : FOR( q = pindx + 1; q <= k; q++ )
1403 : {
1404 552 : IF( LE_16( peak_cand_idx[q], high ) )
1405 : {
1406 355 : peak_cand_idx[q] = 0;
1407 355 : move16();
1408 355 : L_input_abs[q] = 0;
1409 355 : move16();
1410 : }
1411 : }
1412 :
1413 288 : pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m ); /* Q0 */
1414 : }
1415 :
1416 12 : *Npeaks = i;
1417 12 : move16();
1418 12 : IF( GT_16( *Npeaks, HVQ_MIN_PEAKS ) )
1419 : {
1420 12 : test();
1421 12 : IF( GT_16( num_sharp_bands, sub( nsub, 3 ) ) && LE_16( *Npeaks, peak_th ) )
1422 : {
1423 0 : sharp_dist = mult( sharp_dist, inv_nsub ); /*x+15-15=x */
1424 0 : test();
1425 0 : IF( LE_16( sharp_dist, SHARP_DIST_THRES_FX ) && *hvq_hangover < 0 )
1426 : {
1427 0 : *hvq_hangover = add( *hvq_hangover, 1 );
1428 : }
1429 : ELSE
1430 : {
1431 0 : *hqswb_clas = HQ_HVQ; /* Q0 */
1432 0 : move16();
1433 0 : *hvq_hangover = 2; /* Q0 */
1434 0 : move16();
1435 : }
1436 :
1437 : /* update memory */
1438 0 : *prev_Npeaks = *Npeaks; /* Q0 */
1439 0 : move16();
1440 0 : Copy( peaks, prev_peaks, *Npeaks ); /* Q0 */
1441 : }
1442 : ELSE
1443 : {
1444 12 : IF( *hvq_hangover > 0 )
1445 : {
1446 0 : *hqswb_clas = HQ_HVQ; /* Q0 */
1447 0 : move16();
1448 0 : *hvq_hangover = sub( *hvq_hangover, 1 ); /* Q0 */
1449 0 : move16();
1450 : }
1451 : ELSE
1452 : {
1453 12 : *hvq_hangover = -1;
1454 12 : move16();
1455 : }
1456 : }
1457 : }
1458 : ELSE
1459 : {
1460 : /* Zero peaks, likely silence input. */
1461 0 : *hvq_hangover = -1;
1462 0 : move16();
1463 : }
1464 :
1465 12 : IF( EQ_32( L_core_brate, HQ_24k40 ) )
1466 : {
1467 12 : *Npeaks = s_min( HVQ_MAX_PEAKS_24k, *Npeaks ); /* Q0 */
1468 12 : move16();
1469 : }
1470 : ELSE
1471 : {
1472 0 : *Npeaks = s_min( HVQ_MAX_PEAKS_32k, *Npeaks ); /* Q0 */
1473 0 : move16();
1474 : }
1475 : }
1476 : ELSE
1477 : {
1478 32 : *prev_Npeaks = 0;
1479 32 : move16();
1480 32 : *hvq_hangover = 0;
1481 32 : move16();
1482 : }
1483 :
1484 :
1485 44 : return;
1486 : }
|