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