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