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 525862 : 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 525862 : assert( EQ_16( num_tracks, NB_TRACK_FCB_4T ) );
40 :
41 525862 : wordcnt = shr( add( config.bits, 15 ), 4 ); /* ceil(bits/16) */
42 :
43 : /* check if some tracks have more pulses */
44 525862 : restpulses = s_and( (Word16) config.nb_pulse, sub( num_tracks, 1 ) );
45 :
46 : /* cast to short */
47 525862 : idxs = (UWord16 *) idxs32;
48 2224088 : FOR( k = 0; k < wordcnt; k++ )
49 : {
50 1698226 : idxs[k] = (UWord16) index[k];
51 1698226 : move16();
52 : }
53 525862 : idxs[wordcnt] = 0;
54 525862 : move16();
55 :
56 : /*init 32bits wordcnt*/
57 525862 : wordcnt32 = shr( add( wordcnt, 1 ), 1 );
58 :
59 525862 : IF( restpulses )
60 : {
61 : /* check if we need to code track positions */
62 375373 : SWITCH( config.codetrackpos )
63 : {
64 59776 : case TRACKPOS_FREE_THREE:
65 : /* Find track with less pulses */
66 59776 : trackpos = extract_l( L_and( idxs[0], 3 ) );
67 59776 : longshr( idxs32, 2, wordcnt32 );
68 :
69 : /* set number of pulses per track */
70 59776 : set16_fx( pulsestrack, add( shr( (Word16) config.nb_pulse, 2 ), 1 ), 4 );
71 59776 : cast16();
72 59776 : pulsestrack[trackpos] = sub( pulsestrack[trackpos], 1 ); /* this one has less pulses */
73 59776 : move16();
74 59776 : BREAK;
75 19206 : case TRACKPOS_FREE_ONE:
76 : /* Find track with more pulses */
77 19206 : trackpos = extract_l( L_and( idxs[0], 3 ) );
78 19206 : longshr( idxs32, 2, wordcnt32 );
79 :
80 : /* set number of pulses per track */
81 19206 : set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
82 19206 : cast16();
83 19206 : pulsestrack[trackpos] = add( pulsestrack[trackpos], 1 ); /* this one has less pulses */
84 19206 : move16();
85 19206 : 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 228266 : case TRACKPOS_FIXED_FIRST:
100 : /* set number of pulses per track */
101 228266 : set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
102 228266 : cast16();
103 680256 : FOR( k = 0; k < restpulses; k++ )
104 : {
105 451990 : pulsestrack[k] = add( pulsestrack[k], 1 );
106 451990 : move16();
107 : }
108 228266 : BREAK;
109 68125 : case TRACKPOS_FIXED_TWO:
110 : /* 1100, 0110, 0011, 1001 */
111 : /* Find track with less pulses */
112 68125 : trackpos = extract_l( L_and( idxs[0], 3 ) );
113 68125 : longshr( idxs32, 2, wordcnt32 );
114 :
115 : /* set number of pulses per track */
116 68125 : set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
117 68125 : cast16();
118 68125 : pulsestrack[trackpos] = add( pulsestrack[trackpos], 1 );
119 68125 : move16();
120 68125 : trackpos = add( trackpos, 1 );
121 68125 : trackpos = s_and( trackpos, 3 );
122 68125 : pulsestrack[trackpos] = add( pulsestrack[trackpos], 1 );
123 68125 : move16();
124 68125 : BREAK;
125 0 : default:
126 0 : assert( 0 );
127 : BREAK;
128 : }
129 : }
130 : ELSE
131 : {
132 : /* set number of pulses per track */
133 150489 : set16_fx( pulsestrack, shr( (Word16) config.nb_pulse, 2 ), 4 );
134 150489 : cast16();
135 : }
136 :
137 525862 : IF( EQ_16( config.bits, 43 ) )
138 : {
139 33002 : D_ACELP_decode_43bit_fx( idxs, code, pulsestrack );
140 : }
141 : ELSE
142 : {
143 492860 : fcb_pulse_track_joint_decode_fx( idxs, wordcnt, index_n, pulsestrack, num_tracks );
144 1971440 : FOR( track = ( num_tracks - 1 ); track >= 1; track-- )
145 : {
146 1478580 : pulses = pulsestrack[track];
147 1478580 : move16();
148 :
149 1478580 : IF( pulses )
150 : {
151 : /* divide by number of possible states: rest is actual state and
152 : * the integer part goes to next track */
153 1463992 : s = index_n[track];
154 1463992 : move32();
155 : /* decode state to actual pulse positions on track */
156 1463992 : D_ACELP_decode_arithtrack_fx( code + track, s, pulses, num_tracks, 16 );
157 : }
158 : ELSE /* track is empty */
159 : {
160 247996 : FOR( k = track; k < ( 16 * num_tracks ); k += num_tracks )
161 : {
162 233408 : code[k] = 0;
163 233408 : move16();
164 : }
165 : }
166 : }
167 :
168 492860 : s = L_add( index_n[0], 0 );
169 492860 : pulses = pulsestrack[0];
170 492860 : move16();
171 :
172 :
173 492860 : IF( pulses )
174 : {
175 : /* safety check in case of bit errors */
176 488393 : 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 488393 : D_ACELP_decode_arithtrack_fx( code, s, pulses, num_tracks, 16 );
184 : }
185 : ELSE
186 : { /* track is empty */
187 75939 : FOR( k = 0; k < imult1616( 16, num_tracks ); k += num_tracks )
188 : {
189 71472 : code[k] = 0;
190 71472 : move16();
191 : }
192 : }
193 : }
194 : }
195 :
196 1952385 : 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 1952385 : assert( s >= 0 );
203 :
204 33190545 : FOR( k = (tracklen) -1; k >= 0; k-- )
205 : {
206 31238160 : idx = imult1616( k, trackstep );
207 31238160 : v[idx] = 0; /* default: there is no pulse here */
208 31238160 : move16();
209 :
210 36394630 : FOR( ; p; p-- ) /* one pulse placed, so one less left */
211 : {
212 25844516 : IF( LT_32( s, pulsestostates[k][p - 1] ) )
213 : {
214 20688046 : BREAK;
215 : }
216 :
217 5156470 : s = L_sub( s, pulsestostates[k][p - 1] );
218 :
219 5156470 : IF( v[idx] != 0 ) /* there is a pulse here already = sign is known */
220 : {
221 292251 : IF( v[idx] > 0 )
222 : {
223 142494 : v[idx] = add( v[idx], _1_CODE ); /* place one more pulse here */
224 142494 : move16();
225 : }
226 292251 : IF( v[idx] <= 0 )
227 : {
228 149757 : v[idx] = sub( v[idx], _1_CODE ); /* place one more pulse here */
229 149757 : move16();
230 : }
231 : }
232 : ELSE /* this is the first pulse here -> determine sign */
233 : {
234 4864219 : v[idx] = _1_CODE; /* place a negative pulse here */
235 4864219 : move16();
236 4864219 : IF( L_and( s, 0x1 ) != 0 )
237 : {
238 2462372 : v[idx] = negate( _1_CODE ); /* place a negative pulse here */
239 2462372 : move16();
240 : }
241 4864219 : s = L_lshr( s, 1 );
242 : }
243 : }
244 : }
245 1952385 : }
246 :
247 492860 : void fcb_pulse_track_joint_decode_fx( UWord16 *idxs, Word16 wordcnt, UWord32 *index_n, Word16 *pulse_num, Word16 track_num )
248 : {
249 492860 : 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 492860 : indx_flag = 0;
259 492860 : move16();
260 492860 : indx_flag_1 = 0;
261 492860 : move16();
262 492860 : indx_flag_2 = 0;
263 492860 : move16();
264 :
265 2464300 : FOR( track = 0; track < track_num; track++ )
266 : {
267 1971440 : indx_flag = add( indx_flag, shr( pulse_num[track], 2 ) );
268 1971440 : indx_flag_1 = add( indx_flag_1, shr( pulse_num[track], 1 ) );
269 1971440 : indx_flag_2 = add( indx_flag_2, shr( pulse_num[track], 3 ) );
270 : }
271 :
272 492860 : hi_to_low[4] = 1;
273 492860 : move16();
274 492860 : if ( GE_16( indx_flag, track_num ) )
275 : {
276 75589 : hi_to_low[4] = 9;
277 75589 : move16();
278 : }
279 :
280 492860 : hi_to_low[7] = 1;
281 492860 : move16();
282 492860 : if ( GE_16( indx_flag_2, 1 ) )
283 : {
284 40 : hi_to_low[7] = 9;
285 40 : move16();
286 : }
287 :
288 492860 : IF( GE_16( indx_flag_1, track_num ) )
289 : {
290 320676 : IF( GE_16( indx_flag, track_num ) )
291 : {
292 75589 : index = 0;
293 75589 : move32();
294 75589 : IF( GE_16( indx_flag_2, 1 ) )
295 : {
296 40 : FOR( track = sub( wordcnt, 1 ); track >= 6; track-- )
297 : {
298 0 : index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
299 : }
300 40 : index_n[3] = L_add( L_lshl( idxs[5], 8 ), L_and( L_lshr( idxs[4], 8 ), 0xFF ) );
301 40 : move32();
302 40 : index_n[2] = L_and( L_add( L_lshl( idxs[4], 16 ), idxs[3] ), 0xFFFFFF );
303 40 : move32();
304 40 : index_n[1] = L_add( L_lshl( idxs[2], 8 ), L_and( L_lshr( idxs[1], 8 ), 0xFF ) );
305 40 : move32();
306 40 : index_n[0] = L_and( L_add( L_lshl( idxs[1], 16 ), idxs[0] ), 0xFFFFFF );
307 40 : move32();
308 : }
309 : ELSE
310 : {
311 158892 : FOR( track = sub( wordcnt, 1 ); track >= track_num; track-- )
312 : {
313 83343 : index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
314 : }
315 377745 : FOR( track = 0; track < track_num; track++ )
316 : {
317 302196 : index_n[track] = (UWord32) idxs[track];
318 302196 : move32();
319 : }
320 : }
321 : }
322 : ELSE
323 : {
324 245087 : index = 0;
325 245087 : move32();
326 602470 : FOR( track = ( wordcnt - 1 ); track >= 2; track-- )
327 : {
328 357383 : index = L_add( L_lshl( index, 16 ), (UWord32) idxs[track] );
329 : }
330 :
331 245087 : index_n[3] = L_and( (Word32) idxs[1], 0xFF );
332 245087 : move32();
333 245087 : index_n[2] = L_lshr( (Word32) idxs[1], 8 );
334 245087 : move32();
335 245087 : index_n[1] = L_and( (Word32) idxs[0], 0xFF );
336 245087 : move32();
337 245087 : index_n[0] = L_lshr( (Word32) idxs[0], 8 );
338 245087 : move32();
339 : }
340 :
341 320676 : track_num1 = sub( track_num, 1 );
342 320676 : pulse_num1 = pulse_num[track_num1];
343 320676 : move16();
344 320676 : index = L_add( L_lshl( index, hi_to_low[pulse_num1] ), L_lshr( index_n[track_num1], low_len[pulse_num1] ) );
345 1282704 : FOR( track = ( track_num - 1 ); track > 0; track-- )
346 : {
347 962028 : track_num1 = sub( track, 1 );
348 962028 : pulse_num0 = pulse_num[track_num1];
349 962028 : move16();
350 962028 : pulse_num1 = pulse_num[track];
351 962028 : move16();
352 962028 : index = L_add( L_lshl( index, hi_to_low[pulse_num0] ), L_lshr( index_n[track_num1], low_len[pulse_num0] ) );
353 :
354 962028 : iDiv_and_mod_32( index, indx_fact[pulse_num1], &div_tmp, &indx_tmp, 0 );
355 962028 : index_n[track] = L_add( L_and( index_n[track], low_mask[pulse_num1] ), L_lshl( indx_tmp, low_len[pulse_num1] ) );
356 962028 : move32();
357 962028 : index = L_add( div_tmp, 0 );
358 : }
359 320676 : pulse_num1 = pulse_num[0];
360 320676 : move16();
361 320676 : index_n[0] = L_add( L_and( index_n[0], low_mask[pulse_num1] ), L_lshl( index, low_len[pulse_num1] ) );
362 320676 : move32();
363 : }
364 : ELSE
365 : {
366 172184 : index = 0;
367 172184 : move32();
368 538068 : FOR( track = ( wordcnt - 1 ); track >= 0; track-- )
369 : {
370 365884 : index = (UWord32) W_add( UL_lshl( index, 16 ), (UWord32) idxs[track] );
371 : }
372 688736 : FOR( track = 3; track > 0; track-- )
373 : {
374 516552 : pulse_num1 = pulse_num[track];
375 516552 : move16();
376 516552 : index_n[track] = UL_and( index, index_mask_ACELP[pulse_num1] );
377 516552 : move32();
378 516552 : index = UL_lshr( index, index_len[pulse_num1] );
379 : }
380 172184 : index_n[0] = index;
381 172184 : move32();
382 : }
383 :
384 492860 : return;
385 : }
|