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 "rom_com.h" /* Static table prototypes */
8 : #include "prot_fx.h"
9 : #include "ivas_prot_fx.h"
10 :
11 :
12 : /*--------------------------------------------------------------------------*
13 : * fine_gain_pred()
14 : *
15 : * Fine gain prediction
16 : *--------------------------------------------------------------------------*/
17 6201 : void ivas_fine_gain_pred_fx(
18 : const Word16 *sfm_start, /* i : Sub band start indices */
19 : const Word16 *sfm_end, /* i : Sub band end indices */
20 : const Word16 *sfm_size, /* i : Sub band bandwidths */
21 : const Word16 *i_sort, /* i : Energy sorting indices */
22 : const Word16 *K, /* i : Number of pulses per band */
23 : const Word16 *maxpulse, /* i : Maximum pulse per band */
24 : const Word16 *R, /* i : Bits per sub band Q3 */
25 : const Word16 num_sfm, /* i : Number of sub bands */
26 : Word16 *xq, /* i/o: Quantized vector /quantized vector with finegain adj Q15*/
27 : Word16 *y, /* i/o: Quantized vector (int) Q0*/
28 : Word16 *fg_pred, /* o : Predicted fine gains Q12 */
29 : const Word16 core /* i : Core */
30 : )
31 : {
32 : Word16 i, band;
33 : Word16 gp;
34 : Word32 xx;
35 : Word16 accuracy;
36 : Word16 k, bw;
37 :
38 : Word16 shift, bw_idx;
39 : Word16 tmp, exp, exp2;
40 : Word32 L_tmp;
41 : UWord16 lsb;
42 : #ifndef ISSUE_1836_replace_overflow_libcom
43 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
44 : Flag Overflow = 0;
45 : move16();
46 : #endif
47 : #endif
48 :
49 255221 : FOR( band = 0; band < num_sfm; band++ )
50 : {
51 249020 : k = K[i_sort[band]];
52 249020 : move16();
53 :
54 249020 : IF( k > 0 )
55 : {
56 : /* bw, bw_idx only used if k>0 */
57 129046 : bw = sfm_size[i_sort[band]];
58 129046 : move16(); // Extending for IVAS /* allowed. 8, 16, 24,32,40,48,64,80,96*/
59 :
60 129046 : bw_idx = ivas_band_len_idx[shr( bw, 3 )];
61 129046 : move16(); /* bw_idx= 0: 8 */
62 129046 : xx = L_deposit_l( 0 );
63 129046 : shift = ivas_band_len_ener_shift[bw_idx];
64 129046 : move16();
65 1760456 : FOR( i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++ )
66 : {
67 : /*xx += xq[i] * xq[i]; */
68 1631410 : tmp = shr( xq[i], shift ); /*15-shift */
69 1631410 : xx = L_mac0( xx, tmp, tmp ); /*30-2*shift */
70 : }
71 :
72 129046 : IF( xx > 0 )
73 : {
74 : /* Normalize synthesis to RMS=1.0 */
75 : /*gp = (float) sqrt(bw / xx); */
76 129046 : exp = norm_l( xx );
77 129046 : L_tmp = L_shl( xx, exp ); /*2*(15-shift)+exp */
78 129046 : exp = sub( 31, add( exp, sub( 30, shl( shift, 1 ) ) ) );
79 129046 : L_tmp = Isqrt_lc( L_tmp, &exp ); /*31 - exp */
80 129046 : Word16 norm = norm_s( bw );
81 129046 : Word16 tmp1, tmp_exp = sub( 15, norm );
82 129046 : tmp1 = Sqrt16( shl( bw, norm ), &tmp_exp );
83 129046 : tmp1 = shr( tmp1, sub( sub( 15, tmp_exp ), Q11 ) );
84 129046 : Mpy_32_16_ss( L_tmp, tmp1, &L_tmp, &lsb ); /*31-exp+11-15=27-exp */
85 :
86 : #ifdef ISSUE_1836_replace_overflow_libcom
87 129046 : gp = round_fx_sat( L_shl_sat( L_tmp, add( 1, exp ) ) ); /*27-exp+1+exp-16=12 */
88 : #else
89 : gp = round_fx_o( L_shl_o( L_tmp, add( 1, exp ), &Overflow ), &Overflow ); /*27-exp+1+exp-16=12 */
90 : #endif
91 129046 : test();
92 129046 : test();
93 129046 : IF( EQ_16( core, HQ_CORE ) && R != NULL && LE_16( R[i_sort[band]], 256 ) ) /* 256 is 32 in Q3 */
94 : {
95 : /*accuracy = ((float)k/(float)bw)*maxpulse[i_sort[band]]; */
96 118805 : L_tmp = L_mult( k, inv_tbl_fx[bw] ); /*0+15+1 */
97 118805 : exp2 = norm_l( L_tmp );
98 118805 : tmp = round_fx( L_shl( L_tmp, exp2 ) ); /*16+exp2-16 */
99 118805 : L_tmp = L_mult0( maxpulse[i_sort[band]], tmp ); /*0+exp2 */
100 118805 : exp = norm_l( L_tmp );
101 118805 : accuracy = round_fx( L_shl( L_tmp, exp ) ); /*exp2+exp-16=exp-16 */
102 118805 : exp = add( exp, exp2 );
103 :
104 : /*gp *= 1.0f - 0.05f / accuracy; */
105 118805 : tmp = div_s( 13107, accuracy ); /* 0.05 in Q18 */
106 : #ifdef ISSUE_1836_replace_overflow_libcom
107 118805 : tmp = shr_sat( tmp, sub( 34, exp ) ); /*15+18-exp+16-15=34-exp */
108 : #else
109 : tmp = shr_sat( tmp, sub( 34, exp ) ); /*15+18-exp+16-15=34-exp */
110 : #endif
111 118805 : tmp = sub( 32767, tmp );
112 118805 : tmp = s_max( 27554, tmp ); /* Limit attenuation to norm quantizer error, 2^-0.25 in Q15 */
113 118805 : gp = mult_r( tmp, gp ); /*15+12+1-16=12 */
114 : }
115 :
116 129046 : fg_pred[band] = gp;
117 129046 : move16();
118 : }
119 : ELSE
120 : {
121 0 : fg_pred[band] = 0;
122 0 : move16();
123 : }
124 : }
125 : ELSE
126 : {
127 119974 : fg_pred[band] = 0;
128 119974 : move16();
129 3017044 : FOR( i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++ )
130 : {
131 2897070 : y[i] = 0;
132 2897070 : move16();
133 2897070 : xq[i] = 0;
134 2897070 : move16();
135 : }
136 : }
137 : }
138 :
139 6201 : return;
140 : }
141 :
142 22228 : void fine_gain_pred_fx(
143 : const Word16 *sfm_start, /* i : Sub band start indices */
144 : const Word16 *sfm_end, /* i : Sub band end indices */
145 : const Word16 *sfm_size, /* i : Sub band bandwidths */
146 : const Word16 *i_sort, /* i : Energy sorting indices */
147 : const Word16 *K, /* i : Number of pulses per band */
148 : const Word16 *maxpulse, /* i : Maximum pulse per band */
149 : const Word16 *R, /* i : Bits per sub band Q3 */
150 : const Word16 num_sfm, /* i : Number of sub bands */
151 : Word16 *xq, /* i/o: Quantized vector /quantized vector with finegain adj Q15*/
152 : Word16 *y, /* i/o: Quantized vector (int) */
153 : Word16 *fg_pred, /* o : Predicted fine gains Q12 */
154 : const Word16 core /* i : Core */
155 : )
156 : {
157 : Word16 i, band;
158 : Word16 gp;
159 : Word32 xx;
160 : Word16 accuracy;
161 : Word16 k, bw;
162 :
163 : Word16 shift, bw_idx;
164 : Word16 tmp, exp, exp2;
165 : Word32 L_tmp;
166 : UWord16 lsb;
167 : #ifndef ISSUE_1836_replace_overflow_libcom
168 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
169 : Flag Overflow = 0;
170 : move32();
171 : #endif
172 : #endif
173 :
174 187285 : FOR( band = 0; band < num_sfm; band++ )
175 : {
176 165057 : k = K[i_sort[band]];
177 165057 : move16();
178 :
179 165057 : IF( k > 0 )
180 : {
181 : /* bw, bw_idx only used if k>0 */
182 116921 : bw = sfm_size[i_sort[band]];
183 116921 : move16(); /* allowed. 8, 16, 24,32,48,64,80,96 */
184 116921 : bw_idx = band_len_idx[shr( bw, 3 )];
185 116921 : move16(); /* bw_idx= 0: 7 */
186 116921 : xx = L_deposit_l( 0 );
187 116921 : shift = band_len_ener_shift[bw_idx];
188 2004873 : FOR( i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++ )
189 : {
190 : /*xx += xq[i] * xq[i]; */
191 1887952 : tmp = shr( xq[i], shift ); /*15-shift */
192 1887952 : xx = L_mac0( xx, tmp, tmp ); /*30-2*shift */
193 : }
194 :
195 116921 : IF( xx > 0 )
196 : {
197 : /* Normalize synthesis to RMS=1.0 */
198 : /*gp = (float) sqrt(bw / xx); */
199 116921 : exp = norm_l( xx );
200 116921 : L_tmp = L_shl( xx, exp ); /*2*(15-shift)+exp */
201 116921 : exp = sub( 31, add( exp, sub( 30, shl( shift, 1 ) ) ) );
202 116921 : L_tmp = Isqrt_lc( L_tmp, &exp ); /*31 - exp */
203 116921 : Mpy_32_16_ss( L_tmp, fine_gain_pred_sqrt_bw[bw_idx], &L_tmp, &lsb ); /*31-exp+11-15=27-exp */
204 : #ifdef ISSUE_1836_replace_overflow_libcom
205 116921 : gp = round_fx_sat( L_shl_sat( L_tmp, add( 1, exp ) ) ); /*27-exp+1+exp-16=12 */
206 : #else
207 : gp = round_fx_o( L_shl_o( L_tmp, add( 1, exp ), &Overflow ), &Overflow ); /*27-exp+1+exp-16=12 */
208 : #endif
209 116921 : test();
210 116921 : test();
211 116921 : IF( EQ_16( core, HQ_CORE ) && R != NULL && LE_16( R[i_sort[band]], 256 ) ) /* 256 is 32 in Q3 */
212 : {
213 : /*accuracy = ((float)k/(float)bw)*maxpulse[i_sort[band]]; */
214 9713 : L_tmp = L_mult( k, inv_tbl_fx[bw] ); /*0+15+1 */
215 9713 : exp2 = norm_l( L_tmp );
216 9713 : tmp = round_fx( L_shl( L_tmp, exp2 ) ); /*16+exp2-16 */
217 9713 : L_tmp = L_mult0( maxpulse[i_sort[band]], tmp ); /*0+exp2 */
218 9713 : exp = norm_l( L_tmp );
219 9713 : accuracy = round_fx( L_shl( L_tmp, exp ) ); /*exp2+exp-16=exp-16 */
220 9713 : exp = add( exp, exp2 );
221 :
222 : /*gp *= 1.0f - 0.05f / accuracy; */
223 9713 : tmp = div_s( 13107, accuracy ); /* 0.05 in Q18 */
224 : #ifdef ISSUE_1836_replace_overflow_libcom
225 9713 : tmp = shr_sat( tmp, sub( 34, exp ) ); /*15+18-exp+16-15=34-exp */
226 : #else
227 : tmp = shr_sat( tmp, sub( 34, exp ) ); /*15+18-exp+16-15=34-exp */
228 : #endif
229 9713 : tmp = sub( 32767, tmp );
230 9713 : tmp = s_max( 27554, tmp ); /* Limit attenuation to norm quantizer error, 2^-0.25 in Q15 */
231 9713 : gp = mult_r( tmp, gp ); /*15+12+1-16=12 */
232 : }
233 :
234 116921 : fg_pred[band] = gp;
235 116921 : move16();
236 : }
237 : ELSE
238 : {
239 0 : fg_pred[band] = 0;
240 0 : move16();
241 : }
242 : }
243 : ELSE
244 : {
245 48136 : fg_pred[band] = 0;
246 48136 : move16();
247 836304 : FOR( i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++ )
248 : {
249 788168 : y[i] = 0;
250 788168 : move16();
251 788168 : xq[i] = 0;
252 788168 : move16();
253 : }
254 : }
255 : }
256 :
257 22228 : return;
258 : }
259 :
260 : /*--------------------------------------------------------------------------*
261 : * get_max_pulses()
262 : *
263 : * Find the maximum pulse height (in unit pulses) in each band
264 : *--------------------------------------------------------------------------*/
265 :
266 27198 : void get_max_pulses_fx(
267 : const Word16 *band_start, /* i : Sub band start indices */
268 : const Word16 *band_end, /* i : Sub band end indices */
269 : const Word16 *k_sort, /* i : Indices for sorting by energy */
270 : const Word16 *npulses, /* i : Pulses per sub band */
271 : const Word16 BANDS, /* i : Number of bands */
272 : Word16 *inp_vector, /* i/o: Encoded shape vectors (int)Q0*/
273 : Word16 *maxpulse /* o : Maximum pulse height per band Q0*/
274 : )
275 : {
276 : Word16 i, k;
277 : Word16 npul;
278 : Word16 maxp;
279 : Word16 tmp;
280 :
281 438837 : FOR( k = 0; k < BANDS; k++ )
282 : {
283 411639 : npul = npulses[k_sort[k]];
284 411639 : move16();
285 411639 : maxp = 0;
286 411639 : move16();
287 411639 : IF( npul > 0 )
288 : {
289 3698371 : FOR( i = band_start[k_sort[k]]; i < band_end[k_sort[k]]; i++ )
290 : {
291 3454842 : tmp = abs_s( inp_vector[i] );
292 3454842 : if ( GT_16( tmp, maxp ) )
293 : {
294 369399 : maxp = tmp;
295 369399 : move16();
296 : }
297 : }
298 : }
299 411639 : maxpulse[k_sort[k]] = maxp;
300 411639 : move16();
301 : }
302 :
303 27198 : return;
304 : }
305 :
306 : /*--------------------------------------------------------------------------*
307 : * fine_gain_dec()
308 : *
309 : * Fine gain decoder. Decodes fine gain adjustments and applies correction to
310 : * predicted fine gains
311 : *--------------------------------------------------------------------------*/
312 :
313 28429 : void fine_gain_dec_fx(
314 : Decoder_State *st,
315 : const Word16 *ord, /* i : Indices for energy order */
316 : const Word16 num_sfm, /* i : Number of bands */
317 : const Word16 *gain_bits, /* i : Gain adjustment bits per sub band */
318 : Word16 *fg_pred /* i/o: Predicted gains / Corrected gains Q12*/
319 : )
320 : {
321 : Word16 band;
322 : Word16 gbits;
323 : Word16 idx, tmp1, exp1;
324 : Word16 gain_dbq;
325 : Word32 L_tmp;
326 :
327 :
328 442506 : FOR( band = 0; band < num_sfm; band++ )
329 : {
330 414077 : gbits = gain_bits[ord[band]];
331 414077 : move16();
332 414077 : IF( gbits > 0 )
333 : {
334 33802 : IF( fg_pred[band] != 0 )
335 : {
336 33587 : idx = get_next_indice_fx( st, gbits );
337 33587 : gain_dbq = finegain_fx[gbits - 1][idx];
338 33587 : move16();
339 :
340 : /* Update predicted gain with quantized correction */
341 33587 : L_tmp = L_mult0( gain_dbq, 21771 ); /* 21771=0.05*log2(10) */ /* 14+17=31 */
342 33587 : L_tmp = L_shr( L_tmp, 15 );
343 33587 : tmp1 = L_Extract_lc( L_tmp, &exp1 );
344 33587 : tmp1 = abs_s( tmp1 );
345 33587 : tmp1 = extract_l( Pow2( 14, tmp1 ) );
346 33587 : exp1 = sub( 14, exp1 );
347 :
348 33587 : L_tmp = L_mult0( fg_pred[band], tmp1 ); /*12+exp1 */
349 33587 : fg_pred[band] = round_fx_sat( L_shl_sat( L_tmp, sub( 16, exp1 ) ) ); /*12+exp1+16-exp1-16=12 */
350 33587 : move16();
351 : }
352 : }
353 : }
354 :
355 28429 : return;
356 : }
|