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