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 :
173 481908 : IF( pulses )
174 : {
175 : /* safety check in case of bit errors */
176 477431 : IF( GE_64( s, pulsestostates[16][pulses - 1] ) )
177 : {
178 0 : set16_fx( code, 0, L_SUBFR );
179 0 : *BER_detect = 1;
180 0 : move16();
181 0 : return;
182 : }
183 477431 : D_ACELP_decode_arithtrack_fx( code, s, pulses, num_tracks, 16 );
184 : }
185 : ELSE
186 : { /* track is empty */
187 76109 : FOR( k = 0; k < imult1616( 16, num_tracks ); k += num_tracks )
188 : {
189 71632 : code[k] = 0;
190 71632 : move16();
191 : }
192 : }
193 : }
194 : }
195 :
196 1908962 : static void D_ACELP_decode_arithtrack_fx( Word16 v[], Word32 s, Word16 p, Word16 trackstep, Word16 tracklen )
197 : {
198 : Word16 k, idx;
199 :
200 : /*initialy s was UWords32 but it seems that s is never greater then 0x80000000*/
201 : /*this assumption reduces complexity but if it is not true than exit*/
202 1908962 : assert( s >= 0 );
203 :
204 32452354 : FOR( k = (tracklen) -1; k >= 0; k-- )
205 : {
206 30543392 : idx = imult1616( k, trackstep );
207 30543392 : v[idx] = 0; /* default: there is no pulse here */
208 30543392 : move16();
209 :
210 35543010 : FOR( ; p; p-- ) /* one pulse placed, so one less left */
211 : {
212 25152724 : IF( LT_32( s, pulsestostates[k][p - 1] ) )
213 : {
214 20153106 : BREAK;
215 : }
216 :
217 4999618 : s = L_sub( s, pulsestostates[k][p - 1] );
218 :
219 4999618 : IF( v[idx] != 0 ) /* there is a pulse here already = sign is known */
220 : {
221 280864 : IF( v[idx] > 0 )
222 : {
223 138653 : v[idx] = add( v[idx], _1_CODE ); /* place one more pulse here */
224 138653 : move16();
225 : }
226 280864 : IF( v[idx] <= 0 )
227 : {
228 142211 : v[idx] = sub( v[idx], _1_CODE ); /* place one more pulse here */
229 142211 : move16();
230 : }
231 : }
232 : ELSE /* this is the first pulse here -> determine sign */
233 : {
234 4718754 : v[idx] = _1_CODE; /* place a negative pulse here */
235 4718754 : move16();
236 4718754 : IF( L_and( s, 0x1 ) != 0 )
237 : {
238 2364713 : v[idx] = negate( _1_CODE ); /* place a negative pulse here */
239 2364713 : move16();
240 : }
241 4718754 : s = L_lshr( s, 1 );
242 : }
243 : }
244 : }
245 1908962 : }
246 :
247 481908 : void fcb_pulse_track_joint_decode_fx( UWord16 *idxs, Word16 wordcnt, UWord32 *index_n, Word16 *pulse_num, Word16 track_num )
248 : {
249 481908 : Word16 hi_to_low[10] = { 0, 0, 0, 3, 9, 5, 3, 1, 8, 8 };
250 :
251 : UWord32 index;
252 : Word32 indx_tmp;
253 : Word16 indx_flag, indx_flag_1;
254 : Word16 track, track_num1, pulse_num0, pulse_num1;
255 : Word32 div_tmp;
256 : Word16 indx_flag_2;
257 :
258 481908 : indx_flag = 0;
259 481908 : move16();
260 481908 : indx_flag_1 = 0;
261 481908 : move16();
262 481908 : indx_flag_2 = 0;
263 481908 : move16();
264 :
265 2409540 : FOR( track = 0; track < track_num; track++ )
266 : {
267 1927632 : indx_flag = add( indx_flag, shr( pulse_num[track], 2 ) );
268 1927632 : indx_flag_1 = add( indx_flag_1, shr( pulse_num[track], 1 ) );
269 1927632 : indx_flag_2 = add( indx_flag_2, shr( pulse_num[track], 3 ) );
270 : }
271 :
272 481908 : hi_to_low[4] = 1;
273 481908 : move16();
274 481908 : if ( GE_16( indx_flag, track_num ) )
275 : {
276 70385 : hi_to_low[4] = 9;
277 70385 : move16();
278 : }
279 :
280 481908 : hi_to_low[7] = 1;
281 481908 : move16();
282 481908 : if ( GE_16( indx_flag_2, 1 ) )
283 : {
284 25 : hi_to_low[7] = 9;
285 25 : move16();
286 : }
287 :
288 481908 : IF( GE_16( indx_flag_1, track_num ) )
289 : {
290 311872 : IF( GE_16( indx_flag, track_num ) )
291 : {
292 70385 : index = 0;
293 70385 : move32();
294 70385 : IF( GE_16( indx_flag_2, 1 ) )
295 : {
296 25 : FOR( track = sub( wordcnt, 1 ); track >= 6; track-- )
297 : {
298 0 : index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
299 : }
300 25 : index_n[3] = L_add( L_lshl( idxs[5], 8 ), L_and( L_lshr( idxs[4], 8 ), 0xFF ) );
301 25 : move32();
302 25 : index_n[2] = L_and( L_add( L_lshl( idxs[4], 16 ), idxs[3] ), 0xFFFFFF );
303 25 : move32();
304 25 : index_n[1] = L_add( L_lshl( idxs[2], 8 ), L_and( L_lshr( idxs[1], 8 ), 0xFF ) );
305 25 : move32();
306 25 : index_n[0] = L_and( L_add( L_lshl( idxs[1], 16 ), idxs[0] ), 0xFFFFFF );
307 25 : move32();
308 : }
309 : ELSE
310 : {
311 145263 : FOR( track = sub( wordcnt, 1 ); track >= track_num; track-- )
312 : {
313 74903 : index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
314 : }
315 351800 : FOR( track = 0; track < track_num; track++ )
316 : {
317 281440 : index_n[track] = (UWord32) idxs[track];
318 281440 : move32();
319 : }
320 : }
321 : }
322 : ELSE
323 : {
324 241487 : index = 0;
325 241487 : move32();
326 594308 : FOR( track = ( wordcnt - 1 ); track >= 2; track-- )
327 : {
328 352821 : index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
329 : }
330 :
331 241487 : index_n[3] = L_and( (Word32) idxs[1], 0xFF );
332 241487 : move32();
333 241487 : index_n[2] = L_lshr( (Word32) idxs[1], 8 );
334 241487 : move32();
335 241487 : index_n[1] = L_and( (Word32) idxs[0], 0xFF );
336 241487 : move32();
337 241487 : index_n[0] = L_lshr( (Word32) idxs[0], 8 );
338 241487 : move32();
339 : }
340 :
341 311872 : track_num1 = sub( track_num, 1 );
342 311872 : pulse_num1 = pulse_num[track_num1];
343 311872 : move16();
344 311872 : index = L_add( L_lshl( index, hi_to_low[pulse_num1] ), L_lshr( index_n[track_num1], low_len[pulse_num1] ) );
345 1247488 : FOR( track = ( track_num - 1 ); track > 0; track-- )
346 : {
347 935616 : track_num1 = sub( track, 1 );
348 935616 : pulse_num0 = pulse_num[track_num1];
349 935616 : move16();
350 935616 : pulse_num1 = pulse_num[track];
351 935616 : move16();
352 935616 : index = L_add( L_lshl( index, hi_to_low[pulse_num0] ), L_lshr( index_n[track_num1], low_len[pulse_num0] ) );
353 :
354 935616 : iDiv_and_mod_32( index, indx_fact[pulse_num1], &div_tmp, &indx_tmp, 0 );
355 935616 : index_n[track] = L_add( L_and( index_n[track], low_mask[pulse_num1] ), L_lshl( indx_tmp, low_len[pulse_num1] ) );
356 935616 : move32();
357 935616 : index = L_add( div_tmp, 0 );
358 : }
359 311872 : pulse_num1 = pulse_num[0];
360 311872 : move16();
361 311872 : index_n[0] = L_add( L_and( index_n[0], low_mask[pulse_num1] ), L_lshl( index, low_len[pulse_num1] ) );
362 311872 : move32();
363 : }
364 : ELSE
365 : {
366 170036 : index = 0;
367 170036 : move32();
368 531862 : FOR( track = ( wordcnt - 1 ); track >= 0; track-- )
369 : {
370 361826 : index = (UWord32) W_add( UL_lshl( index, 16 ), (UWord32) idxs[track] );
371 : }
372 680144 : FOR( track = 3; track > 0; track-- )
373 : {
374 510108 : pulse_num1 = pulse_num[track];
375 510108 : move16();
376 510108 : index_n[track] = UL_and( index, index_mask_ACELP[pulse_num1] );
377 510108 : move32();
378 510108 : index = UL_lshr( index, index_len[pulse_num1] );
379 : }
380 170036 : index_n[0] = index;
381 170036 : move32();
382 : }
383 :
384 481908 : return;
385 : }
|