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 525319 : 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 525319 : assert( EQ_16( num_tracks, NB_TRACK_FCB_4T ) );
40 :
41 525319 : wordcnt = shr( add( config.bits, 15 ), 4 ); /* ceil(bits/16) */
42 :
43 : /* check if some tracks have more pulses */
44 525319 : restpulses = s_and( (Word16) config.nb_pulse, sub( num_tracks, 1 ) );
45 :
46 : /* cast to short */
47 525319 : idxs = (UWord16 *) idxs32;
48 2224625 : FOR( k = 0; k < wordcnt; k++ )
49 : {
50 1699306 : idxs[k] = (UWord16) index[k];
51 1699306 : move16();
52 : }
53 525319 : idxs[wordcnt] = 0;
54 525319 : move16();
55 :
56 : /*init 32bits wordcnt*/
57 525319 : wordcnt32 = shr( add( wordcnt, 1 ), 1 );
58 :
59 525319 : IF( restpulses )
60 : {
61 : /* check if we need to code track positions */
62 375236 : SWITCH( config.codetrackpos )
63 : {
64 59917 : case TRACKPOS_FREE_THREE:
65 : /* Find track with less pulses */
66 59917 : trackpos = extract_l( L_and( idxs[0], 3 ) );
67 59917 : longshr( idxs32, 2, wordcnt32 );
68 :
69 : /* set number of pulses per track */
70 59917 : set16_fx( pulsestrack, add( shr( (Word16) config.nb_pulse, 2 ), 1 ), 4 );
71 59917 : cast16();
72 59917 : pulsestrack[trackpos] = sub( pulsestrack[trackpos], 1 ); /* this one has less pulses */
73 59917 : move16();
74 59917 : BREAK;
75 18754 : case TRACKPOS_FREE_ONE:
76 : /* Find track with more pulses */
77 18754 : trackpos = extract_l( L_and( idxs[0], 3 ) );
78 18754 : longshr( idxs32, 2, wordcnt32 );
79 :
80 : /* set number of pulses per track */
81 18754 : set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
82 18754 : cast16();
83 18754 : pulsestrack[trackpos] = add( pulsestrack[trackpos], 1 ); /* this one has less pulses */
84 18754 : move16();
85 18754 : 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 228270 : case TRACKPOS_FIXED_FIRST:
100 : /* set number of pulses per track */
101 228270 : set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
102 228270 : cast16();
103 682063 : FOR( k = 0; k < restpulses; k++ )
104 : {
105 453793 : pulsestrack[k] = add( pulsestrack[k], 1 );
106 453793 : move16();
107 : }
108 228270 : BREAK;
109 68295 : case TRACKPOS_FIXED_TWO:
110 : /* 1100, 0110, 0011, 1001 */
111 : /* Find track with less pulses */
112 68295 : trackpos = extract_l( L_and( idxs[0], 3 ) );
113 68295 : longshr( idxs32, 2, wordcnt32 );
114 :
115 : /* set number of pulses per track */
116 68295 : set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
117 68295 : cast16();
118 68295 : pulsestrack[trackpos] = add( pulsestrack[trackpos], 1 );
119 68295 : move16();
120 68295 : trackpos = add( trackpos, 1 );
121 68295 : trackpos = s_and( trackpos, 3 );
122 68295 : pulsestrack[trackpos] = add( pulsestrack[trackpos], 1 );
123 68295 : move16();
124 68295 : BREAK;
125 0 : default:
126 0 : assert( 0 );
127 : BREAK;
128 : }
129 : }
130 : ELSE
131 : {
132 : /* set number of pulses per track */
133 150083 : set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
134 150083 : cast16();
135 : }
136 :
137 525319 : IF( EQ_16( config.bits, 43 ) )
138 : {
139 32931 : D_ACELP_decode_43bit_fx( idxs, code, pulsestrack );
140 : }
141 : ELSE
142 : {
143 492388 : fcb_pulse_track_joint_decode_fx( idxs, wordcnt, index_n, pulsestrack, num_tracks );
144 1969552 : FOR( track = ( num_tracks - 1 ); track >= 1; track-- )
145 : {
146 1477164 : pulses = pulsestrack[track];
147 1477164 : move16();
148 :
149 1477164 : IF( pulses )
150 : {
151 : /* divide by number of possible states: rest is actual state and
152 : * the integer part goes to next track */
153 1462969 : s = index_n[track];
154 1462969 : move32();
155 : /* decode state to actual pulse positions on track */
156 1462969 : D_ACELP_decode_arithtrack_fx( code + track, s, pulses, num_tracks, 16 );
157 : }
158 : ELSE /* track is empty */
159 : {
160 241315 : FOR( k = track; k < ( 16 * num_tracks ); k += num_tracks )
161 : {
162 227120 : code[k] = 0;
163 227120 : move16();
164 : }
165 : }
166 : }
167 :
168 492388 : s = L_add( index_n[0], 0 );
169 492388 : pulses = pulsestrack[0];
170 492388 : move16();
171 :
172 :
173 492388 : IF( pulses )
174 : {
175 : /* safety check in case of bit errors */
176 487974 : 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 487974 : D_ACELP_decode_arithtrack_fx( code, s, pulses, num_tracks, 16 );
184 : }
185 : ELSE
186 : { /* track is empty */
187 75038 : FOR( k = 0; k < imult1616( 16, num_tracks ); k += num_tracks )
188 : {
189 70624 : code[k] = 0;
190 70624 : move16();
191 : }
192 : }
193 : }
194 : }
195 :
196 1950943 : 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 1950943 : assert( s >= 0 );
203 :
204 33166031 : FOR( k = (tracklen) -1; k >= 0; k-- )
205 : {
206 31215088 : idx = imult1616( k, trackstep );
207 31215088 : v[idx] = 0; /* default: there is no pulse here */
208 31215088 : move16();
209 :
210 36384170 : FOR( ; p; p-- ) /* one pulse placed, so one less left */
211 : {
212 25822340 : IF( LT_32( s, pulsestostates[k][p - 1] ) )
213 : {
214 20653258 : BREAK;
215 : }
216 :
217 5169082 : s = L_sub( s, pulsestostates[k][p - 1] );
218 :
219 5169082 : IF( v[idx] != 0 ) /* there is a pulse here already = sign is known */
220 : {
221 295008 : IF( v[idx] > 0 )
222 : {
223 145471 : v[idx] = add( v[idx], _1_CODE ); /* place one more pulse here */
224 145471 : move16();
225 : }
226 295008 : IF( v[idx] <= 0 )
227 : {
228 149537 : v[idx] = sub( v[idx], _1_CODE ); /* place one more pulse here */
229 149537 : move16();
230 : }
231 : }
232 : ELSE /* this is the first pulse here -> determine sign */
233 : {
234 4874074 : v[idx] = _1_CODE; /* place a negative pulse here */
235 4874074 : move16();
236 4874074 : IF( L_and( s, 0x1 ) != 0 )
237 : {
238 2442870 : v[idx] = negate( _1_CODE ); /* place a negative pulse here */
239 2442870 : move16();
240 : }
241 4874074 : s = L_lshr( s, 1 );
242 : }
243 : }
244 : }
245 1950943 : }
246 :
247 492388 : void fcb_pulse_track_joint_decode_fx( UWord16 *idxs, Word16 wordcnt, UWord32 *index_n, Word16 *pulse_num, Word16 track_num )
248 : {
249 492388 : 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 492388 : indx_flag = 0;
259 492388 : move16();
260 492388 : indx_flag_1 = 0;
261 492388 : move16();
262 492388 : indx_flag_2 = 0;
263 492388 : move16();
264 :
265 2461940 : FOR( track = 0; track < track_num; track++ )
266 : {
267 1969552 : indx_flag = add( indx_flag, shr( pulse_num[track], 2 ) );
268 1969552 : indx_flag_1 = add( indx_flag_1, shr( pulse_num[track], 1 ) );
269 1969552 : indx_flag_2 = add( indx_flag_2, shr( pulse_num[track], 3 ) );
270 : }
271 :
272 492388 : hi_to_low[4] = 1;
273 492388 : move16();
274 492388 : if ( GE_16( indx_flag, track_num ) )
275 : {
276 76465 : hi_to_low[4] = 9;
277 76465 : move16();
278 : }
279 :
280 492388 : hi_to_low[7] = 1;
281 492388 : move16();
282 492388 : if ( GE_16( indx_flag_2, 1 ) )
283 : {
284 25 : hi_to_low[7] = 9;
285 25 : move16();
286 : }
287 :
288 492388 : IF( GE_16( indx_flag_1, track_num ) )
289 : {
290 321277 : IF( GE_16( indx_flag, track_num ) )
291 : {
292 76465 : index = 0;
293 76465 : move32();
294 76465 : 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 159888 : FOR( track = sub( wordcnt, 1 ); track >= track_num; track-- )
312 : {
313 83448 : index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
314 : }
315 382200 : FOR( track = 0; track < track_num; track++ )
316 : {
317 305760 : index_n[track] = (UWord32) idxs[track];
318 305760 : move32();
319 : }
320 : }
321 : }
322 : ELSE
323 : {
324 244812 : index = 0;
325 244812 : move32();
326 602233 : FOR( track = ( wordcnt - 1 ); track >= 2; track-- )
327 : {
328 357421 : index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
329 : }
330 :
331 244812 : index_n[3] = L_and( (Word32) idxs[1], 0xFF );
332 244812 : move32();
333 244812 : index_n[2] = L_lshr( (Word32) idxs[1], 8 );
334 244812 : move32();
335 244812 : index_n[1] = L_and( (Word32) idxs[0], 0xFF );
336 244812 : move32();
337 244812 : index_n[0] = L_lshr( (Word32) idxs[0], 8 );
338 244812 : move32();
339 : }
340 :
341 321277 : track_num1 = sub( track_num, 1 );
342 321277 : pulse_num1 = pulse_num[track_num1];
343 321277 : move16();
344 321277 : index = L_add( L_lshl( index, hi_to_low[pulse_num1] ), L_lshr( index_n[track_num1], low_len[pulse_num1] ) );
345 1285108 : FOR( track = ( track_num - 1 ); track > 0; track-- )
346 : {
347 963831 : track_num1 = sub( track, 1 );
348 963831 : pulse_num0 = pulse_num[track_num1];
349 963831 : move16();
350 963831 : pulse_num1 = pulse_num[track];
351 963831 : move16();
352 963831 : index = L_add( L_lshl( index, hi_to_low[pulse_num0] ), L_lshr( index_n[track_num1], low_len[pulse_num0] ) );
353 :
354 963831 : iDiv_and_mod_32( index, indx_fact[pulse_num1], &div_tmp, &indx_tmp, 0 );
355 963831 : index_n[track] = L_add( L_and( index_n[track], low_mask[pulse_num1] ), L_lshl( indx_tmp, low_len[pulse_num1] ) );
356 963831 : move32();
357 963831 : index = L_add( div_tmp, 0 );
358 : }
359 321277 : pulse_num1 = pulse_num[0];
360 321277 : move16();
361 321277 : index_n[0] = L_add( L_and( index_n[0], low_mask[pulse_num1] ), L_lshl( index, low_len[pulse_num1] ) );
362 321277 : move32();
363 : }
364 : ELSE
365 : {
366 171111 : index = 0;
367 171111 : move32();
368 535221 : FOR( track = ( wordcnt - 1 ); track >= 0; track-- )
369 : {
370 364110 : index = (UWord32) W_add( UL_lshl( index, 16 ), (UWord32) idxs[track] );
371 : }
372 684444 : FOR( track = 3; track > 0; track-- )
373 : {
374 513333 : pulse_num1 = pulse_num[track];
375 513333 : move16();
376 513333 : index_n[track] = UL_and( index, index_mask_ACELP[pulse_num1] );
377 513333 : move32();
378 513333 : index = UL_lshr( index, index_len[pulse_num1] );
379 : }
380 171111 : index_n[0] = index;
381 171111 : move32();
382 : }
383 :
384 492388 : return;
385 : }
|