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"
8 : //#include "prot_fx.h"
9 : #include "rom_com.h"
10 : #include "prot_fx.h" /* Function prototypes */
11 : #include "prot_fx_enc.h" /* Function prototypes */
12 :
13 : #define HVQ_ENC_NOISE_DELTA ( (Word16) 3277 ) /* 0.1 in Q15 */
14 :
15 : static Word16 quant_lc_fx( const Word16, Word16 * );
16 :
17 :
18 : /*--------------------------------------------------------------------------*
19 : * hvq_enc_fx()
20 : *
21 : * Harmonic VQ encoder
22 : *--------------------------------------------------------------------------*/
23 1467 : Word16 hvq_enc_ivas_fx( /*o : Consumed bits */
24 : Encoder_State *st_fx, /*i/o: encoder state structure */
25 : const Word32 core_brate, /*i : Total bit rate */
26 : const Word16 hvq_bits, /*i : HVQ bit budget */
27 : const Word16 Npeaks, /*i : Number of peaks */
28 : const Word16 *ynrm, /* i : Envelope coefficients */
29 : Word16 *R, /* i/o: Bit allocation/updated bit allocation */
30 : Word16 *peaks, /* i : Peak pos. / Encoded peak pos. */
31 : Word32 *nf_gains, /* i/o: Noise fill gains / Quant. nf gains Q12*/
32 : Word16 *noise_level, /* o : Quantized noise level Q15*/
33 : const Word32 *pe_gains, /* i : Peak gains */
34 : const Word32 *coefs, /* i : spectrum coefficients in Q12 */
35 : Word32 *coefs_out /* o : encoded spectrum coefficients in Q12 */
36 : )
37 : {
38 : const Word32 *pCoefs;
39 : Word16 bin_th, j, i, n;
40 : Word16 nf_cnt;
41 : Word16 q_noise_level_idx[HVQ_BWE_NOISE_BANDS];
42 : Word16 q_noise_level[HVQ_BWE_NOISE_BANDS];
43 : Word32 d, nf_mean;
44 : Word32 nf, pe, pe_mean;
45 : Word16 bits_used, nBits;
46 : Word16 lb_nfpe;
47 : UWord16 dontCare;
48 : Word32 acc, numerator, denominator;
49 : Word16 expPeMean, expNfMean, expNfpe, expNfpe3, expo, expo3;
50 : Word16 manPeMean, manNfMean, manNfpe, man;
51 : Word16 tmp16, adjust;
52 : #ifndef ISSUE_1867_replace_overflow_libenc
53 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
54 : Flag Overflow = 0;
55 : move32();
56 : #endif
57 : #endif
58 1467 : bits_used = 0;
59 1467 : move16();
60 :
61 1467 : IF( LT_32( core_brate, HQ_BWE_CROSSOVER_BRATE ) )
62 : {
63 854 : bin_th = HVQ_THRES_BIN_24k;
64 854 : move16();
65 854 : n = ( L_FRAME32k - HVQ_THRES_BIN_24k ) / HVQ_BWE_NOISE_BANDS;
66 854 : move16();
67 : }
68 : ELSE
69 : {
70 613 : bin_th = HVQ_THRES_BIN_32k;
71 613 : move16();
72 613 : n = ( L_FRAME32k - HVQ_THRES_BIN_32k ) / HVQ_BWE_NOISE_BANDS;
73 613 : move16();
74 : }
75 :
76 1467 : nf = 800 * 4096L; /* Q12 */
77 1467 : move32();
78 1467 : pe = 800 * 4096L; /* Q12 */
79 1467 : move32();
80 1467 : pCoefs = &coefs[bin_th];
81 :
82 : /* Find HB noise level */
83 4401 : FOR( i = 0; i < HVQ_BWE_NOISE_BANDS; i++ )
84 : {
85 2934 : nf_cnt = 0;
86 2934 : move16();
87 2934 : nf_mean = L_deposit_l( 0 );
88 2934 : pe_mean = L_deposit_l( 0 );
89 554358 : FOR( j = 0; j < n; j++ )
90 : {
91 551424 : d = L_abs( *pCoefs++ ); /* Q12 */
92 :
93 551424 : IF( GT_32( d, pe ) )
94 : {
95 : /* W*pe + (1 - W)*d = (pe - d)*W + d */
96 31027 : acc = L_sub( pe, d );
97 31027 : Mpy_32_16_ss( acc, HVQ_BWE_WEIGHT2_FX, &acc, &dontCare );
98 31027 : pe = L_add( acc, d ); /* in Q12 and always positive */
99 : }
100 : ELSE
101 : {
102 : /* W*pe + (1 - W)*d = (pe - d)*W + d */
103 520397 : acc = L_sub( pe, d );
104 520397 : Mpy_32_16_ss( acc, HVQ_BWE_WEIGHT1_FX, &acc, &dontCare );
105 520397 : pe = L_add( acc, d ); /* in Q12 and always positive */
106 :
107 520397 : IF( GT_32( d, nf ) )
108 : {
109 388886 : acc = L_sub( nf, d );
110 388886 : Mpy_32_16_ss( acc, HVQ_BWE_WEIGHT1_FX, &acc, &dontCare );
111 388886 : nf = L_add( acc, d ); /* in Q12 and always positive */
112 : }
113 : ELSE
114 : {
115 131511 : acc = L_sub( nf, d );
116 131511 : Mpy_32_16_ss( acc, HVQ_BWE_WEIGHT2_FX, &acc, &dontCare );
117 131511 : nf = L_add( acc, d ); /* in Q12 always positive */
118 : }
119 520397 : nf_mean = L_add( nf_mean, nf ); /* in Q12 and always positive */
120 520397 : nf_cnt = add( nf_cnt, 1 ); /* Q0 */
121 : }
122 :
123 : #ifdef ISSUE_1867_replace_overflow_libenc
124 551424 : pe_mean = L_add_sat( pe_mean, pe ); /* in Q12 and always positive */
125 : #else
126 : pe_mean = L_add_o( pe_mean, pe, &Overflow ); /* in Q12 and always positive */
127 : #endif
128 : }
129 :
130 2934 : IF( pe_mean > 0 )
131 : {
132 2934 : expPeMean = norm_l( pe_mean ); /* exponent */
133 2934 : manPeMean = extract_h( L_shl( pe_mean, expPeMean ) ); /* mantissa */
134 2934 : expNfMean = norm_l( nf_mean ); /* exponent */
135 2934 : manNfMean = extract_h( L_shl( nf_mean, expNfMean ) ); /* mantissa */
136 :
137 2934 : numerator = L_mult0( manNfMean, n );
138 2934 : IF( nf_cnt > 0 )
139 : {
140 2934 : denominator = L_mult0( manPeMean, nf_cnt ); /* in Q15 */
141 : }
142 : ELSE
143 : {
144 0 : denominator = L_mult0( manPeMean, 1 ); /* in Q15 */
145 : }
146 2934 : manNfpe = ratio( numerator, denominator, &expo ); /* manNfpe in Q14 */
147 2934 : expNfpe = add( sub( expNfMean, expPeMean ), expo );
148 :
149 2934 : tmp16 = mult_r( manNfpe, manNfpe ); /* in Q(14+14+1-16) = Q13 */
150 2934 : tmp16 = mult_r( tmp16, manNfpe ); /* in Q(13+14+1-16) = Q12 */
151 2934 : acc = L_mult( tmp16, HVQ_NFPE_FACTOR_CUBE_FX ); /* in Q(12+6+1) = Q19 */
152 2934 : expNfpe3 = extract_l( L_mult0( expNfpe, 3 ) ); /* Cube operation */
153 : /* Number of bits required to adjust to Q15 */
154 2934 : adjust = add( 19 - ( 15 + 16 ), expNfpe3 ); /* +16 is due to the following extract_h(). */
155 : #ifdef ISSUE_1867_replace_overflow_libenc
156 2934 : noise_level[i] = extract_h( L_shr_sat( acc, adjust ) ); /* noise_level[] in Q15 */
157 : #else
158 : noise_level[i] = extract_h( L_shr_sat( acc, adjust ) ); /* noise_level[] in Q15 */
159 : #endif
160 2934 : move16();
161 2934 : q_noise_level_idx[i] = quant_lc_fx( noise_level[i], &q_noise_level[i] );
162 2934 : move16();
163 : }
164 : ELSE
165 : {
166 0 : q_noise_level_idx[i] = 0;
167 0 : move16();
168 0 : q_noise_level[i] = 0;
169 0 : move16();
170 : }
171 2934 : push_indice( st_fx->hBstr, IND_HVQ_BWE_NL, q_noise_level_idx[i], 2 );
172 2934 : bits_used = add( bits_used, 2 );
173 :
174 2934 : noise_level[i] = q_noise_level[i]; /* in Q15 */
175 2934 : move16();
176 : }
177 :
178 4401 : FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
179 : {
180 2934 : IF( pe_gains[i] != 0 )
181 : {
182 : /* Neither pe_gains[] nor nf_gains[] is zero. */
183 2934 : man = ratio( nf_gains[i], pe_gains[i], &expo ); /* man in Q14 */
184 2934 : tmp16 = mult_r( man, man ); /* in Q(14+14+1-16) = Q13 */
185 2934 : tmp16 = mult_r( tmp16, man ); /* in Q(13+14+1-16) = Q12 */
186 2934 : acc = L_mult( tmp16, HVQ_LB_NFPE_FACTOR_CUBE_FX ); /* in Q(12+9+1) = Q22 */
187 2934 : expo3 = extract_l( L_mult0( expo, 3 ) ); /* Cube operation. */
188 : /* Number of bits required to adjust to Q15 */
189 2934 : adjust = add( 22 - ( 15 + 16 ), expo3 ); /* +16 is due to the following extract_h(). */
190 2934 : lb_nfpe = extract_h( L_shr_sat( acc, adjust ) ); /* noise_level[] in Q15 */
191 2934 : IF( GT_16( lb_nfpe, 16384 ) ) /* in Q15 */
192 : {
193 140 : lb_nfpe = 16384;
194 140 : move16();
195 : }
196 2934 : Mpy_32_16_ss( nf_gains[i], shl_sat( lb_nfpe, 1 ), &nf_gains[i], &dontCare ); /* nf_gains[] in Q12 */
197 : }
198 : ELSE
199 : {
200 0 : nf_gains[i] = 0;
201 0 : move16();
202 : }
203 : }
204 1467 : nBits = peak_vq_enc_ivas_fx( st_fx->hBstr, st_fx->bwidth, coefs, coefs_out, core_brate, sub( hvq_bits, bits_used ),
205 : Npeaks, ynrm, R, peaks, &nf_gains[0] );
206 1467 : bits_used = add( bits_used, nBits );
207 1467 : return bits_used;
208 : }
209 :
210 0 : Word16 hvq_enc_fx( /*o : Consumed bits */
211 : Encoder_State *st_fx, /*i/o: encoder state structure */
212 : const Word32 core_brate, /*i : Total bit rate */
213 : const Word16 hvq_bits, /*i : HVQ bit budget */
214 : const Word16 Npeaks, /*i : Number of peaks */
215 : const Word16 *ynrm, /* i : Envelope coefficients */
216 : Word16 *R, /* i/o: Bit allocation/updated bit allocation */
217 : Word16 *peaks, /* i : Peak pos. / Encoded peak pos. */
218 : Word32 *nf_gains, /* i/o: Noise fill gains / Quant. nf gains */
219 : Word16 *noise_level, /* o : Quantized noise level */
220 : const Word32 *pe_gains, /* i : Peak gains */
221 : const Word32 *coefs, /* i : spectrum coefficients in Q12 */
222 : Word32 *coefs_out /* o : encoded spectrum coefficients in Q12 */
223 : )
224 : {
225 : const Word32 *pCoefs;
226 : Word16 bin_th, j, i, n;
227 : Word16 nf_cnt;
228 : Word16 q_noise_level_idx[HVQ_BWE_NOISE_BANDS];
229 : Word16 q_noise_level[HVQ_BWE_NOISE_BANDS];
230 : Word32 d, nf_mean;
231 : Word32 nf, pe, pe_mean;
232 : Word16 bits_used, nBits;
233 : Word16 lb_nfpe;
234 : UWord16 dontCare;
235 : Word32 acc, numerator, denominator;
236 : Word16 expPeMean, expNfMean, expNfpe, expNfpe3, expo, expo3;
237 : Word16 manPeMean, manNfMean, manNfpe, man;
238 : Word16 tmp16, adjust;
239 : #ifndef ISSUE_1867_replace_overflow_libenc
240 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
241 : Flag Overflow = 0;
242 : move32();
243 : #endif
244 : #endif
245 0 : bits_used = 0;
246 0 : move16();
247 :
248 0 : IF( LT_32( core_brate, HQ_BWE_CROSSOVER_BRATE ) )
249 : {
250 0 : bin_th = HVQ_THRES_BIN_24k;
251 0 : move16();
252 0 : n = ( L_FRAME32k - HVQ_THRES_BIN_24k ) / HVQ_BWE_NOISE_BANDS;
253 0 : move16();
254 : }
255 : ELSE
256 : {
257 0 : bin_th = HVQ_THRES_BIN_32k;
258 0 : move16();
259 0 : n = ( L_FRAME32k - HVQ_THRES_BIN_32k ) / HVQ_BWE_NOISE_BANDS;
260 0 : move16();
261 : }
262 :
263 0 : nf = 800 * 4096L; /* Q12 */
264 0 : move32();
265 0 : pe = 800 * 4096L; /* Q12 */
266 0 : move32();
267 0 : pCoefs = &coefs[bin_th];
268 :
269 : /* Find HB noise level */
270 0 : FOR( i = 0; i < HVQ_BWE_NOISE_BANDS; i++ )
271 : {
272 0 : nf_cnt = 0;
273 0 : move16();
274 0 : nf_mean = L_deposit_l( 0 );
275 0 : pe_mean = L_deposit_l( 0 );
276 0 : FOR( j = 0; j < n; j++ )
277 : {
278 0 : d = L_abs( *pCoefs++ ); /* Q12 */
279 :
280 0 : IF( GT_32( d, pe ) )
281 : {
282 : /* W*pe + (1 - W)*d = (pe - d)*W + d */
283 0 : acc = L_sub( pe, d );
284 0 : Mpy_32_16_ss( acc, HVQ_BWE_WEIGHT2_FX, &acc, &dontCare );
285 0 : pe = L_add( acc, d ); /* in Q12 and always positive */
286 : }
287 : ELSE
288 : {
289 : /* W*pe + (1 - W)*d = (pe - d)*W + d */
290 0 : acc = L_sub( pe, d );
291 0 : Mpy_32_16_ss( acc, HVQ_BWE_WEIGHT1_FX, &acc, &dontCare );
292 0 : pe = L_add( acc, d ); /* in Q12 and always positive */
293 :
294 0 : IF( GT_32( d, nf ) )
295 : {
296 0 : acc = L_sub( nf, d );
297 0 : Mpy_32_16_ss( acc, HVQ_BWE_WEIGHT1_FX, &acc, &dontCare );
298 0 : nf = L_add( acc, d ); /* in Q12 and always positive */
299 : }
300 : ELSE
301 : {
302 0 : acc = L_sub( nf, d );
303 0 : Mpy_32_16_ss( acc, HVQ_BWE_WEIGHT2_FX, &acc, &dontCare );
304 0 : nf = L_add( acc, d ); /* in Q12 always positive */
305 : }
306 0 : nf_mean = L_add( nf_mean, nf ); /* in Q12 and always positive */
307 0 : nf_cnt = add( nf_cnt, 1 ); /* Q0 */
308 : }
309 :
310 : #ifdef ISSUE_1867_replace_overflow_libenc
311 0 : pe_mean = L_add_sat( pe_mean, pe ); /* in Q12 and always positive */
312 : #else
313 : pe_mean = L_add_o( pe_mean, pe, &Overflow ); /* in Q12 and always positive */
314 : #endif
315 : }
316 :
317 0 : IF( pe_mean > 0 )
318 : {
319 0 : expPeMean = norm_l( pe_mean ); /* exponent */
320 0 : manPeMean = extract_h( L_shl( pe_mean, expPeMean ) ); /* mantissa */
321 0 : expNfMean = norm_l( nf_mean ); /* exponent */
322 0 : manNfMean = extract_h( L_shl( nf_mean, expNfMean ) ); /* mantissa */
323 :
324 0 : numerator = L_mult0( manNfMean, n );
325 0 : IF( nf_cnt > 0 )
326 : {
327 0 : denominator = L_mult0( manPeMean, nf_cnt ); /* in Q15 */
328 : }
329 : ELSE
330 : {
331 0 : denominator = L_mult0( manPeMean, 1 ); /* in Q15 */
332 : }
333 0 : manNfpe = ratio( numerator, denominator, &expo ); /* manNfpe in Q14 */
334 0 : expNfpe = add( sub( expNfMean, expPeMean ), expo );
335 :
336 0 : tmp16 = mult_r( manNfpe, manNfpe ); /* in Q(14+14+1-16) = Q13 */
337 0 : tmp16 = mult_r( tmp16, manNfpe ); /* in Q(13+14+1-16) = Q12 */
338 0 : acc = L_mult( tmp16, HVQ_NFPE_FACTOR_CUBE_FX ); /* in Q(12+6+1) = Q19 */
339 0 : expNfpe3 = extract_l( L_mult0( expNfpe, 3 ) ); /* Cube operation */
340 : /* Number of bits required to adjust to Q15 */
341 0 : adjust = add( 19 - ( 15 + 16 ), expNfpe3 ); /* +16 is due to the following extract_h(). */
342 0 : noise_level[i] = extract_h( L_shr_sat( acc, adjust ) ); /* noise_level[] in Q15 */
343 0 : move16();
344 0 : q_noise_level_idx[i] = quant_lc_fx( noise_level[i], &q_noise_level[i] );
345 0 : move16();
346 : }
347 : ELSE
348 : {
349 0 : q_noise_level_idx[i] = 0;
350 0 : move16();
351 0 : q_noise_level[i] = 0;
352 0 : move16();
353 : }
354 0 : push_indice( st_fx->hBstr, IND_HVQ_BWE_NL, q_noise_level_idx[i], 2 );
355 0 : bits_used = add( bits_used, 2 );
356 :
357 0 : noise_level[i] = q_noise_level[i]; /* in Q15 */
358 0 : move16();
359 : }
360 :
361 0 : FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
362 : {
363 0 : IF( pe_gains[i] != 0 )
364 : {
365 : /* Neither pe_gains[] nor nf_gains[] is zero. */
366 0 : man = ratio( nf_gains[i], pe_gains[i], &expo ); /* man in Q14 */
367 0 : tmp16 = mult_r( man, man ); /* in Q(14+14+1-16) = Q13 */
368 0 : tmp16 = mult_r( tmp16, man ); /* in Q(13+14+1-16) = Q12 */
369 0 : acc = L_mult( tmp16, HVQ_LB_NFPE_FACTOR_CUBE_FX ); /* in Q(12+9+1) = Q22 */
370 0 : expo3 = extract_l( L_mult0( expo, 3 ) ); /* Cube operation. */
371 : /* Number of bits required to adjust to Q15 */
372 0 : adjust = add( 22 - ( 15 + 16 ), expo3 ); /* +16 is due to the following extract_h(). */
373 0 : lb_nfpe = extract_h( L_shr_sat( acc, adjust ) ); /* noise_level[] in Q15 */
374 0 : IF( lb_nfpe > 16384 ) /* in Q15 */
375 : {
376 0 : lb_nfpe = 16384;
377 0 : move16();
378 : }
379 0 : Mpy_32_16_ss( nf_gains[i], shl_sat( lb_nfpe, 1 ), &nf_gains[i], &dontCare ); /* nf_gains[] in Q12 */
380 : }
381 : ELSE
382 : {
383 0 : nf_gains[i] = 0;
384 0 : move16();
385 : }
386 : }
387 0 : nBits = peak_vq_enc_fx( st_fx->hBstr, st_fx->bwidth, coefs, coefs_out, core_brate, sub( hvq_bits, bits_used ),
388 : Npeaks, ynrm, R, peaks, &nf_gains[0] );
389 0 : move16();
390 0 : bits_used = add( bits_used, nBits );
391 0 : return bits_used;
392 : }
393 :
394 : /*-----------------------------------------------------------------------------
395 : * quant()
396 : *
397 : * Quantize the noise to one of the levels in {0, 0.1, 0.2, 0.3}
398 : *----------------------------------------------------------------------------*/
399 2934 : static Word16 quant_lc_fx( const Word16 x, Word16 *qx )
400 : {
401 : Word16 indx;
402 :
403 2934 : IF( LT_16( x, HVQ_ENC_NOISE_DELTA / 2 ) )
404 : {
405 2258 : indx = 0;
406 2258 : move16();
407 2258 : *qx = 0;
408 2258 : move16();
409 : }
410 676 : ELSE IF( LT_16( x, 3 * HVQ_ENC_NOISE_DELTA / 2 ) )
411 : {
412 226 : indx = 1;
413 226 : move16();
414 226 : *qx = HVQ_ENC_NOISE_DELTA;
415 226 : move16();
416 : }
417 450 : ELSE IF( LT_16( x, 5 * HVQ_ENC_NOISE_DELTA / 2 ) )
418 : {
419 145 : indx = 2;
420 145 : move16();
421 145 : *qx = 2 * HVQ_ENC_NOISE_DELTA;
422 145 : move16();
423 : }
424 : ELSE
425 : {
426 305 : indx = 3;
427 305 : move16();
428 305 : *qx = 3 * HVQ_ENC_NOISE_DELTA;
429 305 : move16();
430 : }
431 :
432 2934 : return indx;
433 : }
|