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 <memory.h>
7 : #include <assert.h>
8 : #include "options.h"
9 : #include "basop_util.h"
10 : #include "prot_fx.h"
11 : #include "rom_com.h"
12 : #include "rom_basop_util.h"
13 : #define _1_CODE 0x200 /*codebook excitation Q9 */
14 :
15 : /*---------------------------------------------------------------------*
16 : * Local function prototypes
17 : *---------------------------------------------------------------------*/
18 : static void D_ACELP_decode_arithtrack_fx( Word16 v[], Word32 s, Word16 p, Word16 trackstep, Word16 tracklen );
19 :
20 : /*---------------------------------------------------------------------*
21 : * Function D_ACELP_indexing_fx()
22 : *
23 : *---------------------------------------------------------------------*/
24 :
25 514781 : void D_ACELP_indexing_fx(
26 : Word16 code[], // Q9
27 : PulseConfig config,
28 : Word16 num_tracks,
29 : Word16 index[],
30 : Word16 *BER_detect )
31 : {
32 : Word16 track, pulses, k, pulsestrack[NB_TRACK_FCB_4T];
33 : Word32 s;
34 : Word16 trackpos;
35 : UWord16 *idxs;
36 : UWord32 idxs32[4], index_n[NB_TRACK_FCB_4T];
37 : Word16 restpulses, wordcnt, wordcnt32;
38 :
39 514781 : assert( EQ_16( num_tracks, NB_TRACK_FCB_4T ) );
40 :
41 514781 : wordcnt = shr( add( config.bits, 15 ), 4 ); /* ceil(bits/16) */
42 :
43 : /* check if some tracks have more pulses */
44 514781 : restpulses = s_and( (Word16) config.nb_pulse, sub( num_tracks, 1 ) );
45 :
46 : /* cast to short */
47 514781 : idxs = (UWord16 *) idxs32;
48 2167514 : FOR( k = 0; k < wordcnt; k++ )
49 : {
50 1652733 : idxs[k] = (UWord16) index[k];
51 1652733 : move16();
52 : }
53 514781 : idxs[wordcnt] = 0;
54 514781 : move16();
55 :
56 : /*init 32bits wordcnt*/
57 514781 : wordcnt32 = shr( add( wordcnt, 1 ), 1 );
58 :
59 514781 : IF( restpulses )
60 : {
61 : /* check if we need to code track positions */
62 369304 : SWITCH( config.codetrackpos )
63 : {
64 59682 : case TRACKPOS_FREE_THREE:
65 : /* Find track with less pulses */
66 59682 : trackpos = extract_l( L_and( idxs[0], 3 ) );
67 59682 : longshr( idxs32, 2, wordcnt32 );
68 :
69 : /* set number of pulses per track */
70 59682 : set16_fx( pulsestrack, add( shr( (Word16) config.nb_pulse, 2 ), 1 ), 4 );
71 59682 : cast16();
72 59682 : pulsestrack[trackpos] = sub( pulsestrack[trackpos], 1 ); /* this one has less pulses */
73 59682 : move16();
74 59682 : BREAK;
75 18527 : case TRACKPOS_FREE_ONE:
76 : /* Find track with more pulses */
77 18527 : trackpos = extract_l( L_and( idxs[0], 3 ) );
78 18527 : longshr( idxs32, 2, wordcnt32 );
79 :
80 : /* set number of pulses per track */
81 18527 : set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
82 18527 : cast16();
83 18527 : pulsestrack[trackpos] = add( pulsestrack[trackpos], 1 ); /* this one has less pulses */
84 18527 : move16();
85 18527 : BREAK;
86 0 : case TRACKPOS_FIXED_EVEN:
87 : /* Pulses on even tracks */
88 0 : pulsestrack[0] = shr( add( (Word16) config.nb_pulse, 1 ), 1 );
89 0 : cast16();
90 0 : move16();
91 0 : pulsestrack[1] = 0;
92 0 : move16();
93 0 : pulsestrack[2] = shr( (Word16) config.nb_pulse, 1 );
94 0 : cast16();
95 0 : move16();
96 0 : pulsestrack[3] = 0;
97 0 : move16();
98 0 : BREAK;
99 222921 : case TRACKPOS_FIXED_FIRST:
100 : /* set number of pulses per track */
101 222921 : set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
102 222921 : cast16();
103 666584 : FOR( k = 0; k < restpulses; k++ )
104 : {
105 443663 : pulsestrack[k] = add( pulsestrack[k], 1 );
106 443663 : move16();
107 : }
108 222921 : BREAK;
109 68174 : case TRACKPOS_FIXED_TWO:
110 : /* 1100, 0110, 0011, 1001 */
111 : /* Find track with less pulses */
112 68174 : trackpos = extract_l( L_and( idxs[0], 3 ) );
113 68174 : longshr( idxs32, 2, wordcnt32 );
114 :
115 : /* set number of pulses per track */
116 68174 : set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
117 68174 : cast16();
118 68174 : pulsestrack[trackpos] = add( pulsestrack[trackpos], 1 );
119 68174 : move16();
120 68174 : trackpos = add( trackpos, 1 );
121 68174 : trackpos = s_and( trackpos, 3 );
122 68174 : pulsestrack[trackpos] = add( pulsestrack[trackpos], 1 );
123 68174 : move16();
124 68174 : BREAK;
125 0 : default:
126 0 : assert( 0 );
127 : BREAK;
128 : }
129 : }
130 : ELSE
131 : {
132 : /* set number of pulses per track */
133 145477 : set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
134 145477 : cast16();
135 : }
136 :
137 514781 : IF( EQ_16( config.bits, 43 ) )
138 : {
139 32873 : D_ACELP_decode_43bit_fx( idxs, code, pulsestrack );
140 : }
141 : ELSE
142 : {
143 481908 : fcb_pulse_track_joint_decode_fx( idxs, wordcnt, index_n, pulsestrack, num_tracks );
144 1927632 : FOR( track = ( num_tracks - 1 ); track >= 1; track-- )
145 : {
146 1445724 : pulses = pulsestrack[track];
147 1445724 : move16();
148 :
149 1445724 : IF( pulses )
150 : {
151 : /* divide by number of possible states: rest is actual state and
152 : * the integer part goes to next track */
153 1431531 : s = index_n[track];
154 1431531 : move32();
155 : /* decode state to actual pulse positions on track */
156 1431531 : D_ACELP_decode_arithtrack_fx( code + track, s, pulses, num_tracks, 16 );
157 : }
158 : ELSE /* track is empty */
159 : {
160 241281 : FOR( k = track; k < ( 16 * num_tracks ); k += num_tracks )
161 : {
162 227088 : code[k] = 0;
163 227088 : move16();
164 : }
165 : }
166 : }
167 :
168 481908 : s = L_add( index_n[0], 0 );
169 481908 : pulses = pulsestrack[0];
170 481908 : move16();
171 :
172 : #ifndef FIX_1378_ACELP_OUT_OF_BOUNDS
173 : /* safety check in case of bit errors */
174 : IF( GE_64( s, pulsestostates[16][pulses - 1] ) )
175 : {
176 : set16_fx( code, 0, L_SUBFR );
177 : *BER_detect = 1;
178 : move16();
179 : return;
180 : }
181 : #endif
182 :
183 481908 : IF( pulses )
184 : {
185 : #ifdef FIX_1378_ACELP_OUT_OF_BOUNDS
186 : /* safety check in case of bit errors */
187 477431 : IF( GE_64( s, pulsestostates[16][pulses - 1] ) )
188 : {
189 0 : set16_fx( code, 0, L_SUBFR );
190 0 : *BER_detect = 1;
191 0 : move16();
192 0 : return;
193 : }
194 : #endif
195 477431 : D_ACELP_decode_arithtrack_fx( code, s, pulses, num_tracks, 16 );
196 : }
197 : ELSE
198 : { /* track is empty */
199 76109 : FOR( k = 0; k < imult1616( 16, num_tracks ); k += num_tracks )
200 : {
201 71632 : code[k] = 0;
202 71632 : move16();
203 : }
204 : }
205 : }
206 : }
207 :
208 1908962 : static void D_ACELP_decode_arithtrack_fx( Word16 v[], Word32 s, Word16 p, Word16 trackstep, Word16 tracklen )
209 : {
210 : Word16 k, idx;
211 :
212 : /*initialy s was UWords32 but it seems that s is never greater then 0x80000000*/
213 : /*this assumption reduces complexity but if it is not true than exit*/
214 1908962 : assert( s >= 0 );
215 :
216 32452354 : FOR( k = (tracklen) -1; k >= 0; k-- )
217 : {
218 30543392 : idx = imult1616( k, trackstep );
219 30543392 : v[idx] = 0; /* default: there is no pulse here */
220 30543392 : move16();
221 :
222 35543010 : FOR( ; p; p-- ) /* one pulse placed, so one less left */
223 : {
224 25152724 : IF( LT_32( s, pulsestostates[k][p - 1] ) )
225 : {
226 20153106 : BREAK;
227 : }
228 :
229 4999618 : s = L_sub( s, pulsestostates[k][p - 1] );
230 :
231 4999618 : IF( v[idx] != 0 ) /* there is a pulse here already = sign is known */
232 : {
233 280864 : IF( v[idx] > 0 )
234 : {
235 138653 : v[idx] = add( v[idx], _1_CODE ); /* place one more pulse here */
236 138653 : move16();
237 : }
238 280864 : IF( v[idx] <= 0 )
239 : {
240 142211 : v[idx] = sub( v[idx], _1_CODE ); /* place one more pulse here */
241 142211 : move16();
242 : }
243 : }
244 : ELSE /* this is the first pulse here -> determine sign */
245 : {
246 4718754 : v[idx] = _1_CODE; /* place a negative pulse here */
247 4718754 : move16();
248 4718754 : IF( L_and( s, 0x1 ) != 0 )
249 : {
250 2364713 : v[idx] = negate( _1_CODE ); /* place a negative pulse here */
251 2364713 : move16();
252 : }
253 4718754 : s = L_lshr( s, 1 );
254 : }
255 : }
256 : }
257 1908962 : }
258 :
259 481908 : void fcb_pulse_track_joint_decode_fx( UWord16 *idxs, Word16 wordcnt, UWord32 *index_n, Word16 *pulse_num, Word16 track_num )
260 : {
261 481908 : Word16 hi_to_low[10] = { 0, 0, 0, 3, 9, 5, 3, 1, 8, 8 };
262 :
263 : UWord32 index;
264 : Word32 indx_tmp;
265 : Word16 indx_flag, indx_flag_1;
266 : Word16 track, track_num1, pulse_num0, pulse_num1;
267 : Word32 div_tmp;
268 : Word16 indx_flag_2;
269 :
270 481908 : indx_flag = 0;
271 481908 : move16();
272 481908 : indx_flag_1 = 0;
273 481908 : move16();
274 481908 : indx_flag_2 = 0;
275 481908 : move16();
276 :
277 2409540 : FOR( track = 0; track < track_num; track++ )
278 : {
279 1927632 : indx_flag = add( indx_flag, shr( pulse_num[track], 2 ) );
280 1927632 : indx_flag_1 = add( indx_flag_1, shr( pulse_num[track], 1 ) );
281 1927632 : indx_flag_2 = add( indx_flag_2, shr( pulse_num[track], 3 ) );
282 : }
283 :
284 481908 : hi_to_low[4] = 1;
285 481908 : move16();
286 481908 : if ( GE_16( indx_flag, track_num ) )
287 : {
288 70385 : hi_to_low[4] = 9;
289 70385 : move16();
290 : }
291 :
292 481908 : hi_to_low[7] = 1;
293 481908 : move16();
294 481908 : if ( GE_16( indx_flag_2, 1 ) )
295 : {
296 25 : hi_to_low[7] = 9;
297 25 : move16();
298 : }
299 :
300 481908 : IF( GE_16( indx_flag_1, track_num ) )
301 : {
302 311872 : IF( GE_16( indx_flag, track_num ) )
303 : {
304 70385 : index = 0;
305 70385 : move32();
306 70385 : IF( GE_16( indx_flag_2, 1 ) )
307 : {
308 25 : FOR( track = sub( wordcnt, 1 ); track >= 6; track-- )
309 : {
310 0 : index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
311 : }
312 25 : index_n[3] = L_add( L_lshl( idxs[5], 8 ), L_and( L_lshr( idxs[4], 8 ), 0xFF ) );
313 25 : move32();
314 25 : index_n[2] = L_and( L_add( L_lshl( idxs[4], 16 ), idxs[3] ), 0xFFFFFF );
315 25 : move32();
316 25 : index_n[1] = L_add( L_lshl( idxs[2], 8 ), L_and( L_lshr( idxs[1], 8 ), 0xFF ) );
317 25 : move32();
318 25 : index_n[0] = L_and( L_add( L_lshl( idxs[1], 16 ), idxs[0] ), 0xFFFFFF );
319 25 : move32();
320 : }
321 : ELSE
322 : {
323 145263 : FOR( track = sub( wordcnt, 1 ); track >= track_num; track-- )
324 : {
325 74903 : index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
326 : }
327 351800 : FOR( track = 0; track < track_num; track++ )
328 : {
329 281440 : index_n[track] = (UWord32) idxs[track];
330 281440 : move32();
331 : }
332 : }
333 : }
334 : ELSE
335 : {
336 241487 : index = 0;
337 241487 : move32();
338 594308 : FOR( track = ( wordcnt - 1 ); track >= 2; track-- )
339 : {
340 352821 : index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
341 : }
342 :
343 241487 : index_n[3] = L_and( (Word32) idxs[1], 0xFF );
344 241487 : move32();
345 241487 : index_n[2] = L_lshr( (Word32) idxs[1], 8 );
346 241487 : move32();
347 241487 : index_n[1] = L_and( (Word32) idxs[0], 0xFF );
348 241487 : move32();
349 241487 : index_n[0] = L_lshr( (Word32) idxs[0], 8 );
350 241487 : move32();
351 : }
352 :
353 311872 : track_num1 = sub( track_num, 1 );
354 311872 : pulse_num1 = pulse_num[track_num1];
355 311872 : move16();
356 311872 : index = L_add( L_lshl( index, hi_to_low[pulse_num1] ), L_lshr( index_n[track_num1], low_len[pulse_num1] ) );
357 1247488 : FOR( track = ( track_num - 1 ); track > 0; track-- )
358 : {
359 935616 : track_num1 = sub( track, 1 );
360 935616 : pulse_num0 = pulse_num[track_num1];
361 935616 : move16();
362 935616 : pulse_num1 = pulse_num[track];
363 935616 : move16();
364 935616 : index = L_add( L_lshl( index, hi_to_low[pulse_num0] ), L_lshr( index_n[track_num1], low_len[pulse_num0] ) );
365 :
366 935616 : iDiv_and_mod_32( index, indx_fact[pulse_num1], &div_tmp, &indx_tmp, 0 );
367 935616 : index_n[track] = L_add( L_and( index_n[track], low_mask[pulse_num1] ), L_lshl( indx_tmp, low_len[pulse_num1] ) );
368 935616 : move32();
369 935616 : index = L_add( div_tmp, 0 );
370 : }
371 311872 : pulse_num1 = pulse_num[0];
372 311872 : move16();
373 311872 : index_n[0] = L_add( L_and( index_n[0], low_mask[pulse_num1] ), L_lshl( index, low_len[pulse_num1] ) );
374 311872 : move32();
375 : }
376 : ELSE
377 : {
378 170036 : index = 0;
379 170036 : move32();
380 531862 : FOR( track = ( wordcnt - 1 ); track >= 0; track-- )
381 : {
382 361826 : index = (UWord32) W_add( UL_lshl( index, 16 ), (UWord32) idxs[track] );
383 : }
384 680144 : FOR( track = 3; track > 0; track-- )
385 : {
386 510108 : pulse_num1 = pulse_num[track];
387 510108 : move16();
388 510108 : index_n[track] = UL_and( index, index_mask_ACELP[pulse_num1] );
389 510108 : move32();
390 510108 : index = UL_lshr( index, index_len[pulse_num1] );
391 : }
392 170036 : index_n[0] = index;
393 170036 : move32();
394 : }
395 :
396 481908 : return;
397 : }
|