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 35150 : 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 35150 : Flag Overflow = 0;
44 35150 : move16();
45 : #endif
46 :
47 700483 : FOR( band = 0; band < num_sfm; band++ )
48 : {
49 665333 : k = K[i_sort[band]];
50 665333 : move16();
51 :
52 665333 : IF( k > 0 )
53 : {
54 : /* bw, bw_idx only used if k>0 */
55 374032 : bw = sfm_size[i_sort[band]];
56 374032 : move16(); // Extending for IVAS /* allowed. 8, 16, 24,32,40,48,64,80,96*/
57 :
58 374032 : bw_idx = ivas_band_len_idx[shr( bw, 3 )];
59 374032 : move16(); /* bw_idx= 0: 8 */
60 374032 : xx = L_deposit_l( 0 );
61 374032 : shift = ivas_band_len_ener_shift[bw_idx];
62 374032 : move16();
63 5486614 : FOR( i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++ )
64 : {
65 : /*xx += xq[i] * xq[i]; */
66 5112582 : tmp = shr( xq[i], shift ); /*15-shift */
67 5112582 : xx = L_mac0( xx, tmp, tmp ); /*30-2*shift */
68 : }
69 :
70 374032 : IF( xx > 0 )
71 : {
72 : /* Normalize synthesis to RMS=1.0 */
73 : /*gp = (float) sqrt(bw / xx); */
74 374032 : exp = norm_l( xx );
75 374032 : L_tmp = L_shl( xx, exp ); /*2*(15-shift)+exp */
76 374032 : exp = sub( 31, add( exp, sub( 30, shl( shift, 1 ) ) ) );
77 374032 : L_tmp = Isqrt_lc( L_tmp, &exp ); /*31 - exp */
78 374032 : Word16 norm = norm_s( bw );
79 374032 : Word16 tmp1, tmp_exp = sub( 15, norm );
80 374032 : tmp1 = Sqrt16( shl( bw, norm ), &tmp_exp );
81 374032 : tmp1 = shr( tmp1, sub( sub( 15, tmp_exp ), Q11 ) );
82 374032 : Mpy_32_16_ss( L_tmp, tmp1, &L_tmp, &lsb ); /*31-exp+11-15=27-exp */
83 :
84 374032 : gp = round_fx_o( L_shl_o( L_tmp, add( 1, exp ), &Overflow ), &Overflow ); /*27-exp+1+exp-16=12 */
85 374032 : test();
86 374032 : test();
87 374032 : 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 241825 : L_tmp = L_mult( k, inv_tbl_fx[bw] ); /*0+15+1 */
91 241825 : exp2 = norm_l( L_tmp );
92 241825 : tmp = round_fx( L_shl( L_tmp, exp2 ) ); /*16+exp2-16 */
93 241825 : L_tmp = L_mult0( maxpulse[i_sort[band]], tmp ); /*0+exp2 */
94 241825 : exp = norm_l( L_tmp );
95 241825 : accuracy = round_fx( L_shl( L_tmp, exp ) ); /*exp2+exp-16=exp-16 */
96 241825 : exp = add( exp, exp2 );
97 :
98 : /*gp *= 1.0f - 0.05f / accuracy; */
99 241825 : tmp = div_s( 13107, accuracy ); /* 0.05 in Q18 */
100 241825 : tmp = shr_o( tmp, sub( 34, exp ), &Overflow ); /*15+18-exp+16-15=34-exp */
101 241825 : tmp = sub( 32767, tmp );
102 241825 : tmp = s_max( 27554, tmp ); /* Limit attenuation to norm quantizer error, 2^-0.25 in Q15 */
103 241825 : gp = mult_r( tmp, gp ); /*15+12+1-16=12 */
104 : }
105 :
106 374032 : fg_pred[band] = gp;
107 374032 : move16();
108 : }
109 : ELSE
110 : {
111 0 : fg_pred[band] = 0;
112 0 : move16();
113 : }
114 : }
115 : ELSE
116 : {
117 291301 : fg_pred[band] = 0;
118 291301 : move16();
119 6961127 : FOR( i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++ )
120 : {
121 6669826 : y[i] = 0;
122 6669826 : move16();
123 6669826 : xq[i] = 0;
124 6669826 : move16();
125 : }
126 : }
127 : }
128 :
129 35150 : return;
130 : }
131 :
132 24026 : 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 24026 : Flag Overflow = 0;
159 24026 : move32();
160 : #endif
161 :
162 205771 : FOR( band = 0; band < num_sfm; band++ )
163 : {
164 181745 : k = K[i_sort[band]];
165 181745 : move16();
166 :
167 181745 : IF( k > 0 )
168 : {
169 : /* bw, bw_idx only used if k>0 */
170 131767 : bw = sfm_size[i_sort[band]];
171 131767 : move16(); /* allowed. 8, 16, 24,32,48,64,80,96 */
172 131767 : bw_idx = band_len_idx[shr( bw, 3 )];
173 131767 : move16(); /* bw_idx= 0: 7 */
174 131767 : xx = L_deposit_l( 0 );
175 131767 : shift = band_len_ener_shift[bw_idx];
176 2281063 : FOR( i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++ )
177 : {
178 : /*xx += xq[i] * xq[i]; */
179 2149296 : tmp = shr( xq[i], shift ); /*15-shift */
180 2149296 : xx = L_mac0( xx, tmp, tmp ); /*30-2*shift */
181 : }
182 :
183 131767 : IF( xx > 0 )
184 : {
185 : /* Normalize synthesis to RMS=1.0 */
186 : /*gp = (float) sqrt(bw / xx); */
187 131767 : exp = norm_l( xx );
188 131767 : L_tmp = L_shl( xx, exp ); /*2*(15-shift)+exp */
189 131767 : exp = sub( 31, add( exp, sub( 30, shl( shift, 1 ) ) ) );
190 131767 : L_tmp = Isqrt_lc( L_tmp, &exp ); /*31 - exp */
191 131767 : Mpy_32_16_ss( L_tmp, fine_gain_pred_sqrt_bw[bw_idx], &L_tmp, &lsb ); /*31-exp+11-15=27-exp */
192 131767 : gp = round_fx_o( L_shl_o( L_tmp, add( 1, exp ), &Overflow ), &Overflow ); /*27-exp+1+exp-16=12 */
193 131767 : test();
194 131767 : test();
195 131767 : 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 18590 : L_tmp = L_mult( k, inv_tbl_fx[bw] ); /*0+15+1 */
199 18590 : exp2 = norm_l( L_tmp );
200 18590 : tmp = round_fx( L_shl( L_tmp, exp2 ) ); /*16+exp2-16 */
201 18590 : L_tmp = L_mult0( maxpulse[i_sort[band]], tmp ); /*0+exp2 */
202 18590 : exp = norm_l( L_tmp );
203 18590 : accuracy = round_fx( L_shl( L_tmp, exp ) ); /*exp2+exp-16=exp-16 */
204 18590 : exp = add( exp, exp2 );
205 :
206 : /*gp *= 1.0f - 0.05f / accuracy; */
207 18590 : tmp = div_s( 13107, accuracy ); /* 0.05 in Q18 */
208 18590 : tmp = shr_o( tmp, sub( 34, exp ), &Overflow ); /*15+18-exp+16-15=34-exp */
209 18590 : tmp = sub( 32767, tmp );
210 18590 : tmp = s_max( 27554, tmp ); /* Limit attenuation to norm quantizer error, 2^-0.25 in Q15 */
211 18590 : gp = mult_r( tmp, gp ); /*15+12+1-16=12 */
212 : }
213 :
214 131767 : fg_pred[band] = gp;
215 131767 : move16();
216 : }
217 : ELSE
218 : {
219 0 : fg_pred[band] = 0;
220 0 : move16();
221 : }
222 : }
223 : ELSE
224 : {
225 49978 : fg_pred[band] = 0;
226 49978 : move16();
227 879970 : FOR( i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++ )
228 : {
229 829992 : y[i] = 0;
230 829992 : move16();
231 829992 : xq[i] = 0;
232 829992 : move16();
233 : }
234 : }
235 : }
236 :
237 24026 : return;
238 : }
239 :
240 : /*--------------------------------------------------------------------------*
241 : * get_max_pulses()
242 : *
243 : * Find the maximum pulse height (in unit pulses) in each band
244 : *--------------------------------------------------------------------------*/
245 :
246 56484 : 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 898282 : FOR( k = 0; k < BANDS; k++ )
262 : {
263 841798 : npul = npulses[k_sort[k]];
264 841798 : move16();
265 841798 : maxp = 0;
266 841798 : move16();
267 841798 : IF( npul > 0 )
268 : {
269 7622917 : FOR( i = band_start[k_sort[k]]; i < band_end[k_sort[k]]; i++ )
270 : {
271 7122398 : tmp = abs_s( inp_vector[i] );
272 7122398 : if ( GT_16( tmp, maxp ) )
273 : {
274 756909 : maxp = tmp;
275 756909 : move16();
276 : }
277 : }
278 : }
279 841798 : maxpulse[k_sort[k]] = maxp;
280 841798 : move16();
281 : }
282 :
283 56484 : 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 : }
|