Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 :
6 : #include <stdint.h>
7 : #include <assert.h>
8 : #include "options.h"
9 : //#include "prot_fx.h"
10 : #include "basop_util.h"
11 : #include "cnst.h"
12 : #include "prot_fx.h" /* Function prototypes */
13 : #include "prot_fx_enc.h" /* Function prototypes */
14 : #include "stat_enc.h"
15 : #include "rom_com.h"
16 : #include "rom_com_fx.h"
17 : #include "rom_enc.h"
18 :
19 :
20 : #define _1_Q9 0x200
21 :
22 :
23 : /*
24 : * E_ACELP_toeplitz_mul_fx
25 : *
26 : * Parameters:
27 : * R I: coefficients of Toeplitz matrix (Q9)
28 : * c I: input vector Q_xn
29 : * d O: output vector, exponent = j
30 : *
31 : * Function:
32 : * Multiplication of Toeplitz matrix with vector c, such that
33 : * d = toeplitz(R)*c
34 : * Vector length is L_SUBFR
35 : */
36 406825 : Word16 E_ACELP_toeplitz_mul_fx(
37 : const Word16 R[], /* Q9 */
38 : const Word16 c[], /* Qx */
39 : Word16 d[], /* exp(j) */
40 : const Word16 L_subfr, /* Q0 */
41 : const Word16 highrate /* Q0 */
42 : )
43 : {
44 : static const Word16 step = 4;
45 : Word16 k, j, i;
46 : Word32 s;
47 : Word32 y32[L_SUBFR16k], L_maxloc, L_tot;
48 :
49 :
50 406825 : assert( L_subfr <= L_SUBFR16k );
51 :
52 :
53 : /* first keep the result on 32 bits and find absolute maximum */
54 406825 : L_tot = L_deposit_l( 1 );
55 :
56 2034125 : FOR( k = 0; k < step; k++ )
57 : {
58 1627300 : L_maxloc = L_deposit_l( 0 );
59 27664100 : FOR( i = k; i < L_subfr; i += step )
60 : {
61 26036800 : s = L_mult( R[i], c[0] ); /* Q10 + Qx */
62 820566025 : FOR( j = 1; j < i; j++ )
63 : {
64 794529225 : s = L_mac( s, R[i - j], c[j] ); /* Q10 + Qx */
65 : }
66 871825975 : FOR( ; j < L_subfr; j++ )
67 : {
68 845789175 : s = L_mac( s, R[j - i], c[j] ); /* Q10 + Qx */
69 : }
70 :
71 26036800 : y32[i] = s;
72 26036800 : move32();
73 26036800 : s = L_abs( s );
74 26036800 : L_maxloc = L_max( s, L_maxloc ); /* Q10 + Qx */
75 : }
76 : /* tot += 3*max / 8 */
77 1627300 : L_maxloc = L_shr( L_maxloc, 2 );
78 : /* Do not warn saturation of L_tot, since its for headroom estimation. */
79 : BASOP_SATURATE_WARNING_OFF_EVS
80 1627300 : L_tot = L_add_sat( L_tot, L_maxloc ); /* +max/4 */
81 1627300 : L_maxloc = L_shr( L_maxloc, 1 );
82 1627300 : L_tot = L_add_sat( L_tot, L_maxloc ); /* +max/8 */
83 1627300 : if ( highrate )
84 : {
85 1615220 : L_tot = L_add_sat( L_tot, L_maxloc ); /* +max/8 */
86 : }
87 1627300 : L_maxloc = L_shr( L_maxloc, 1 );
88 1627300 : if ( highrate )
89 : {
90 1615220 : L_tot = L_add_sat( L_tot, L_maxloc ); /* +max/16 */
91 : }
92 : BASOP_SATURATE_WARNING_ON_EVS
93 : }
94 :
95 : /* Find the number of right shifts to do on y32[] so that */
96 : /* 6.0 x sumation of max of dn[] in each track not saturate. */
97 : /* high-rate: 9.0 x sumation of max of dn[] in each track */
98 :
99 : /* Limit exponent to avoid overflows elsewhere. */
100 406825 : j = s_min( sub( norm_l( L_tot ), 4 + 16 ), 15 - 16 ); /* 4 -> 16 x tot */
101 :
102 406825 : Copy_Scale_sig_32_16( y32, d, L_subfr, j ); /* exp(j) */
103 :
104 406825 : return j;
105 : }
106 :
107 64164 : void E_ACELP_weighted_code(
108 : const Word16 code[], /* i: code Q9*/
109 : const Word16 H[], /* i: impulse response Q*/
110 : Word16 Q, /* i: Q format of H */
111 : Word16 y[] /* o: weighted code Q9*/
112 : )
113 : {
114 : Word16 i, j, k, one, n, nz[L_SUBFR];
115 : Word32 L_tmp;
116 :
117 : /* Collect nonzeros */
118 64164 : n = 0;
119 64164 : move16();
120 4170660 : FOR( i = 0; i < L_SUBFR; ++i )
121 : {
122 4106496 : if ( code[i] != 0 )
123 : {
124 526920 : nz[n++] = i;
125 526920 : move16();
126 : }
127 : }
128 64164 : assert( n > 0 );
129 :
130 64164 : one = shl( 1, Q );
131 64164 : Q = sub( 15, Q );
132 :
133 : /* Generate weighted code */
134 64164 : j = nz[0];
135 64164 : move16();
136 64164 : set16_fx( y, 0, j );
137 3780685 : FOR( k = 0; k < L_SUBFR - j; k++ )
138 : {
139 3716521 : L_tmp = L_mult( code[j], H[k] ); /* Q10 + Q */
140 3716521 : y[j + k] = extract_h( L_shl( L_tmp, Q ) ); /* Q9 */
141 : }
142 :
143 526920 : FOR( i = 1; i < n; ++i )
144 : {
145 462756 : j = nz[i];
146 462756 : move16();
147 13307946 : FOR( k = 0; k < L_SUBFR - j; k++ )
148 : {
149 12845190 : L_tmp = L_mult( y[j + k], one );
150 12845190 : L_tmp = L_mac( L_tmp, code[j], H[k] ); /* Q10 + Q */
151 12845190 : y[j + k] = extract_h( L_shl( L_tmp, Q ) ); /* Q9*/
152 : }
153 : }
154 64164 : }
155 :
156 6409 : void E_ACELP_conv(
157 : const Word16 xn2[], /* i Qx*/
158 : const Word16 h2[], /* i Q12*/
159 : Word16 cn2[] /* o Q0*/
160 : )
161 : {
162 : Word16 i, k;
163 : Word32 L_tmp;
164 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
165 6409 : Flag Overflow = 0;
166 : #endif
167 416585 : FOR( k = 0; k < L_SUBFR; k++ )
168 : {
169 : /*cn2[k] = xn2[k]; */
170 : Word64 L_tmp_64;
171 410176 : L_tmp_64 = W_deposit32_l( L_mult( xn2[k], 0x800 ) ); /* 4Q11 */
172 13330720 : FOR( i = 0; i < k; i++ )
173 : {
174 : /*cn2[k]-=cn2[i]*h2[k-i];*/
175 12920544 : L_tmp_64 = W_msu0_16_16( L_tmp_64, cn2[i], h2[k - i] ); /*h2 4Q11*/
176 : }
177 410176 : L_tmp = W_sat_l( L_tmp_64 ); /* 4Q11 */
178 410176 : cn2[k] = round_fx_o( L_shl_o( L_tmp, 5, &Overflow ), &Overflow ); /* Q0 */
179 : }
180 6409 : }
181 :
182 400416 : void E_ACELP_conv_ivas_fx(
183 : const Word16 xn2[], /* i Qnew - 1*/
184 : const Word16 h2[], /* i Q12*/
185 : Word16 cn2[] /* o Qnew*/
186 : )
187 : {
188 : Word16 i, k;
189 : Word32 L_tmp;
190 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
191 400416 : Flag Overflow = 0;
192 : #endif
193 26027040 : FOR( k = 0; k < L_SUBFR; k++ )
194 : {
195 : /*cn2[k] = xn2[k]; */
196 : Word64 L_tmp_64;
197 25626624 : L_tmp_64 = W_deposit32_l( L_mult0( xn2[k], 0x800 ) ); /* Qnew -1 + 12 */
198 832865280 : FOR( i = 0; i < k; i++ )
199 : {
200 : /*cn2[k]-=cn2[i]*h2[k-i];*/
201 807238656 : L_tmp_64 = W_msu0_16_16( L_tmp_64, cn2[i], h2[k - i] ); /*Qnew + 11*/
202 : }
203 25626624 : L_tmp = W_sat_l( L_tmp_64 ); /* Qnew + 11 */
204 25626624 : cn2[k] = round_fx_o( L_shl_o( L_tmp, 5, &Overflow ), &Overflow ); /* Qnew*/
205 25626624 : move16();
206 : }
207 400416 : }
208 188246 : void E_ACELP_build_code(
209 : Word16 nb_pulse, /* i Q0*/
210 : const Word16 codvec[], /* i Q0*/
211 : const Word16 sign[], /* i Q0*/
212 : Word16 code[], /* o Q9*/
213 : Word16 ind[] /* o Q0*/
214 : )
215 : {
216 : Word16 i, k, val, index, track, tmp, vec[4];
217 :
218 188246 : set16_fx( code, 0, L_SUBFR );
219 188246 : set16_fx( ind, -1, NPMAXPT * 4 );
220 :
221 : /* use vec to store point counter */
222 188246 : vec[0] = NPMAXPT * 0 - 1;
223 188246 : move16();
224 188246 : vec[1] = NPMAXPT * 1 - 1;
225 188246 : move16();
226 188246 : vec[2] = NPMAXPT * 2 - 1;
227 188246 : move16();
228 188246 : vec[3] = NPMAXPT * 3 - 1;
229 188246 : move16();
230 :
231 1250263 : FOR( k = 0; k < nb_pulse; ++k )
232 : {
233 1062017 : i = codvec[k]; /* read pulse position Q0*/
234 1062017 : move16();
235 1062017 : val = sign[i]; /* read sign Q0*/
236 1062017 : move16();
237 :
238 1062017 : index = shr( i, 2 ); /* pos of pulse (0..15) */
239 1062017 : track = s_and( i, 4 - 1 ); /* i % 4; */
240 :
241 1062017 : tmp = add( code[i], _1_Q9 ); /* Q9 */
242 1062017 : if ( val <= 0 )
243 : {
244 535922 : tmp = sub( code[i], _1_Q9 ); /* Q9 */
245 : }
246 1062017 : code[i] = tmp; /* Q9 */
247 1062017 : move16();
248 :
249 1062017 : if ( val <= 0 )
250 : {
251 535922 : index = add( index, 16 ); /* Q0 */
252 : }
253 :
254 : /* Calculate Current Store Index (we started at -1) so we increment first */
255 1062017 : i = add( vec[track], 1 ); /* Q0 */
256 : /* Save Next Store Index */
257 1062017 : vec[track] = i; /* Q0 */
258 1062017 : move16();
259 :
260 1062017 : ind[i] = index; /* Q0 */
261 1062017 : move16();
262 : }
263 188246 : }
264 :
265 2159474 : void E_ACELP_setup_pulse_search_pos(
266 : const PulseConfig *config, /* i: pulse configuration */
267 : Word16 k, /* i: interation number Q0*/
268 : UWord8 ipos[] /* o: pulse search positions Q0*/
269 : )
270 : {
271 : Word16 restpulses, iPulse;
272 :
273 : /* copy search order from hash-table */
274 2159474 : assert( config->nb_pulse + ( k * 4 ) <= 40 );
275 :
276 2159474 : copyWord8( (const Word8 *) E_ROM_tipos + ( k * 4 ), (Word8 *) ipos, config->nb_pulse );
277 :
278 : /* if all tracks do not have equal number of pulses */
279 2159474 : restpulses = s_and( config->nb_pulse, 3 );
280 :
281 2159474 : IF( restpulses )
282 : {
283 1581554 : SWITCH( config->codetrackpos )
284 : {
285 890193 : case TRACKPOS_FIXED_FIRST: /* fixed track positions, starting from left */
286 : /* add tracks from left */
287 2689062 : FOR( iPulse = 0; iPulse < restpulses; iPulse++ )
288 : {
289 1798869 : ipos[config->nb_pulse - restpulses + iPulse] = (UWord8) iPulse; /* Q0 */
290 1798869 : move16();
291 : }
292 : /* Put the same track on the next position, because the 1-pulse search
293 : * will access it to determine if this could be in any track. */
294 890193 : ipos[config->nb_pulse] = ipos[config->nb_pulse - 1]; /* Q0 */
295 890193 : move16();
296 890193 : BREAK;
297 0 : case TRACKPOS_FIXED_EVEN: /* fixed track positions, odd tracks */
298 : /* odd tracks, switch order for every iteration */
299 0 : ipos[config->nb_pulse - restpulses] = (UWord8) s_and( lshl( k, 1 ), 2 ); /* Q0 */
300 0 : move16(); /* 0 for even k, 2 for odd */
301 0 : ipos[config->nb_pulse - restpulses + 1] = (UWord8) s_xor( ipos[config->nb_pulse - restpulses], 2 ); /* Q0 */
302 0 : move16(); /* 2 for even k, 0 for odd */
303 0 : BREAK;
304 292276 : case TRACKPOS_FIXED_TWO: /* two tracks instead of four */
305 : /* Put the next track on the next position, because the 1-pulse search
306 : * will access it to determine if this could be in any track. */
307 292276 : ipos[config->nb_pulse] = (UWord8) s_and( add( ipos[config->nb_pulse - 1], 1 ), 3 ); /* Q0 */
308 292276 : move16();
309 292276 : BREAK;
310 399085 : default: /* one or three free track positions */
311 : /* copy an extra position from table - 1pulse search will access this */
312 399085 : ipos[config->nb_pulse] = E_ROM_tipos[add( shl( k, 2 ), config->nb_pulse )]; /* Q0 */
313 399085 : move16();
314 399085 : BREAK;
315 : }
316 577920 : }
317 2159474 : }
|