Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <stdint.h>
38 : #include "options.h"
39 : #include "prot_fx.h"
40 : #include "wmc_auto.h"
41 :
42 : /*-------------------------------------------------------------*
43 : * Local function prototypes
44 : *-------------------------------------------------------------*/
45 :
46 : /*-------------------------------------------------------------*
47 : * procedure lerp_flt() *
48 : * *
49 : * *
50 : *-------------------------------------------------------------*/
51 :
52 : /*-------------------------------------------------------------*
53 : * procedure lerp_proc_flt() *
54 : * *
55 : * *
56 : *-------------------------------------------------------------*/
57 :
58 : /*-------------------------------------------------------------*
59 : * Local constants
60 : *-------------------------------------------------------------*/
61 :
62 : #define shift_e ( 16 - 1 )
63 : #define pos_e ( 16 - 1 )
64 : /*-------------------------------------------------------------*
65 : * Local function prototypes
66 : *-------------------------------------------------------------*/
67 :
68 : static void lerp_proc( const Word16 *f, Word16 *f_out, Word16 bufferNewSize, Word16 bufferOldSize );
69 :
70 : /*-------------------------------------------------------------*
71 : * procedure lerp() *
72 : * *
73 : * *
74 : *-------------------------------------------------------------*/
75 :
76 866336 : void lerp( const Word16 *f /*Qx*/, Word16 *f_out /*Qx*/, Word16 bufferNewSize /*Q0*/, Word16 bufferOldSize /*Q0*/ )
77 : {
78 : Word16 tmp1, tmp2, tmpexp;
79 866336 : BASOP_Util_Divide_MantExp( bufferNewSize, 0, bufferOldSize, 0, &tmp1, &tmpexp );
80 866336 : tmp1 = shr( tmp1, 3 ); /*Q12*/
81 866336 : tmp1 = shl( tmp1, tmpexp ); /*Q12+tmpexp*/
82 :
83 866336 : BASOP_Util_Divide_MantExp( bufferOldSize, 0, bufferNewSize, 0, &tmp2, &tmpexp );
84 866336 : tmp2 = shr( tmp2, 3 ); /*Q12*/
85 866336 : tmp2 = shl( tmp2, tmpexp ); /*Q12+tmpexp*/
86 866336 : IF( GT_16( tmp1, 16224 /*3.9609375 in Q12*/ ) )
87 : {
88 0 : Word16 tmpNewSize = shl( bufferOldSize, 1 ); /*Q0*/
89 0 : WHILE( GT_16( bufferNewSize, bufferOldSize ) )
90 : {
91 0 : BASOP_Util_Divide_MantExp( bufferNewSize, 0, bufferOldSize, 0, &tmp1, &tmpexp );
92 0 : tmp1 = shr( tmp1, 3 ); /*Q12*/
93 0 : tmp1 = shl( tmp1, tmpexp ); /*Q12+tmpexp*/
94 0 : if ( LE_16( tmp1, 16224 /*3.9609375 in Q12*/ ) )
95 : {
96 0 : tmpNewSize = bufferNewSize; /*Q0*/
97 0 : move16();
98 : }
99 :
100 0 : lerp_proc( f, f_out, tmpNewSize, bufferOldSize );
101 :
102 0 : f = f_out; /*Qx*/
103 0 : bufferOldSize = tmpNewSize; /*Q0*/
104 0 : move16();
105 0 : tmpNewSize = shl( tmpNewSize, 1 ); /*Q0*/
106 : }
107 : }
108 866336 : ELSE IF( GT_16( tmp2, 16224 /*3.9609375 in Q12*/ ) )
109 : {
110 0 : Word16 tmpNewSize = shr( bufferOldSize, 1 );
111 0 : WHILE( LT_16( bufferNewSize, bufferOldSize ) )
112 : {
113 0 : BASOP_Util_Divide_MantExp( bufferOldSize, 0, bufferNewSize, 0, &tmp2, &tmpexp );
114 0 : tmp2 = shr( tmp2, 3 ); /*Q12*/
115 0 : tmp2 = shl( tmp2, tmpexp ); /*Q12+tmpexp*/
116 :
117 0 : if ( LE_16( tmp2, 16224 /*3.9609375 in Q12*/ ) )
118 : {
119 0 : tmpNewSize = bufferNewSize; /*Q0*/
120 0 : move16();
121 : }
122 :
123 0 : lerp_proc( f, f_out, tmpNewSize, bufferOldSize );
124 :
125 0 : f = f_out; /*Qx*/
126 0 : bufferOldSize = tmpNewSize; /*Q0*/
127 0 : move16();
128 0 : tmpNewSize = shr( tmpNewSize, 1 ); /*Q0*/
129 : }
130 : }
131 : ELSE
132 : {
133 866336 : lerp_proc( f, f_out, bufferNewSize, bufferOldSize );
134 : }
135 866336 : }
136 : /*-------------------------------------------------------------*
137 : * procedure lerp_proc() *
138 : * *
139 : * *
140 : *-------------------------------------------------------------*/
141 866336 : static void lerp_proc( const Word16 *f /*Qx*/, Word16 *f_out /*Qx*/, Word16 bufferNewSize /*Q0*/, Word16 bufferOldSize /*Q0*/ )
142 : {
143 :
144 : Word16 i, idx, n;
145 : Word16 diff;
146 : Word32 pos, shift;
147 : Word16 buf[2 * L_FRAME_MAX];
148 : Word16 *ptr;
149 :
150 866336 : ptr = f_out; /*Qx*/
151 866336 : test();
152 866336 : test();
153 866336 : test();
154 866336 : if ( ( ( f <= f_out ) && ( f + bufferOldSize >= f_out ) ) || ( ( f_out <= f ) && ( f_out + bufferNewSize >= f ) ) )
155 : {
156 184143 : ptr = buf; /*Qx*/
157 : }
158 :
159 866336 : IF( EQ_16( bufferNewSize, bufferOldSize ) )
160 : {
161 40618 : Copy( f, f_out, bufferNewSize ); /*Qx*/
162 40618 : return;
163 : }
164 :
165 825718 : shift = L_shl( L_deposit_l( div_s( bufferOldSize, shl( bufferNewSize, 4 ) ) ), 4 - shift_e + 16 ); /*Q16*/
166 :
167 825718 : pos = L_sub( L_shr( shift, 1 ), 32768l /*0.5f Q16*/ ); /*Q16*/
168 :
169 : /* Adjust interpolation shift to avoid accessing beyond end of input buffer. */
170 825718 : if ( LT_32( shift, 19661l /*0.3f Q16*/ ) )
171 : {
172 2392 : pos = L_sub( pos, 8520l /*0.13f Q16*/ ); /*Q16*/
173 : }
174 :
175 : assert( pos_e == shift_e );
176 :
177 : /* first point of interpolation */
178 825718 : IF( pos < 0 )
179 : {
180 :
181 169175 : diff = shr( extract_l( pos ), 1 ); /*Q15*/
182 : /*buf[0]=f[0]+pos*(f[1]-f[0]);*/
183 169175 : move16();
184 169175 : *ptr++ = add_sat( f[0], msu_r( L_mult( diff, f[1] ), diff, f[0] ) ); /*Qx*/
185 : }
186 : ELSE
187 : {
188 :
189 656543 : idx = extract_h( pos ); /*Q0*/
190 :
191 656543 : diff = lshr( extract_l( pos ), 1 ); /*Q15*/
192 :
193 656543 : move16();
194 656543 : *ptr++ = add_sat( f[idx], msu_r_sat( L_mult( diff, f[idx + 1] ), diff, f[idx] ) ); /*Qx*/
195 : }
196 :
197 825718 : pos = L_add( pos, shift );
198 825718 : idx = s_max( 0, extract_h( pos ) );
199 :
200 825718 : n = sub( bufferNewSize, 1 );
201 150818840 : FOR( i = 1; i < n; i++ )
202 : {
203 149993122 : diff = lshr( extract_l( pos ), 1 ); /*Q15*/
204 149993122 : if ( pos < 0 )
205 : {
206 4818 : diff = sub( 16384 /*0.5f Q15*/, diff ); /*Q15*/
207 : }
208 149993122 : move16();
209 149993122 : *ptr++ = add_sat( f[idx], msu_r_sat( L_mult( diff, f[idx + 1] ), diff, f[idx] ) ); /*Qx*/
210 :
211 :
212 149993122 : pos = L_add( pos, shift );
213 149993122 : idx = extract_h( pos ); /*Q0*/
214 : }
215 :
216 : /* last point */
217 :
218 825718 : if ( GT_32( pos, L_deposit_h( sub( bufferOldSize, 1 ) ) ) )
219 : {
220 167388 : idx = sub( bufferOldSize, 2 );
221 : }
222 825718 : assert( idx <= 2 * L_FRAME_MAX );
223 :
224 : /* diff = t - point;*/
225 825718 : diff = lshr( extract_l( L_shr( L_sub( pos, L_deposit_h( idx ) ), 1 ) ), 1 ); /*Q15*/
226 :
227 825718 : move16();
228 825718 : *ptr++ = add_sat( f[idx], shl_sat( msu_r_sat( L_mult( diff, f[idx + 1] ), diff, f[idx] ), 1 ) ); /*Qx*/
229 825718 : test();
230 825718 : test();
231 825718 : test();
232 825718 : IF( ( ( f <= f_out ) && ( f + bufferOldSize >= f_out ) ) || ( ( f_out <= f ) && ( f_out + bufferNewSize >= f ) ) )
233 : {
234 153223 : Copy( buf, f_out, bufferNewSize ); /*Qx*/
235 : }
236 : }
237 :
238 :
239 157854 : static void lerp_proc32( Word32 *f /*Qx*/, Word32 *f_out /*Qx*/, Word16 bufferNewSize /*Q0*/, Word16 bufferOldSize /*Q0*/ )
240 : {
241 :
242 : Word16 i, idx, n;
243 : Word16 diff;
244 : Word32 pos, shift;
245 : Word32 buf[2 * L_FRAME_MAX];
246 : Word32 *ptr;
247 :
248 157854 : ptr = f_out; /*Qx*/
249 157854 : test();
250 157854 : test();
251 157854 : test();
252 157854 : if ( ( ( f <= f_out ) && ( f + bufferOldSize >= f_out ) ) || ( ( f_out <= f ) && ( f_out + bufferNewSize >= f ) ) )
253 : {
254 49983 : ptr = buf; /*Qx*/
255 : }
256 :
257 157854 : IF( EQ_16( bufferNewSize, bufferOldSize ) )
258 : {
259 37004 : Copy32( f, f_out, bufferNewSize ); /*Qx*/
260 37004 : return;
261 : }
262 :
263 120850 : shift = L_shl( L_deposit_l( div_s( bufferOldSize, shl( bufferNewSize, 4 ) ) ), add( sub( 4, shift_e ), Q16 ) ); /*Q16*/
264 :
265 120850 : pos = L_sub( L_shr( shift, 1 ), 32768l /*0.5f Q16*/ ); /*Q16*/
266 :
267 : /* Adjust interpolation shift to avoid accessing beyond end of input buffer. */
268 120850 : if ( LT_32( shift, 19661l /*0.3f Q16*/ ) )
269 : {
270 2183 : pos = L_sub( pos, 8520l /*0.13f Q16*/ ); /*Q16*/
271 : }
272 :
273 : assert( pos_e == shift_e );
274 :
275 : /* first point of interpolation */
276 120850 : IF( pos < 0 )
277 : {
278 :
279 39487 : diff = shr( extract_l( pos ), 1 ); /*Q15*/
280 : /*buf[0]=f[0]+pos*(f[1]-f[0]);*/
281 39487 : *ptr++ = L_add_sat( f[0], Mpy_32_16_1( L_sub( f[1], f[0] ), diff ) ); /*Qx*/
282 39487 : move32();
283 : }
284 : ELSE
285 : {
286 :
287 81363 : idx = extract_h( pos ); /*Q0*/
288 81363 : diff = lshr( extract_l( pos ), 1 ); /*Q15*/
289 81363 : *ptr++ = L_add_sat( f[idx], Mpy_32_16_1( L_sub( f[( idx + 1 )], f[idx] ), diff ) ); /*Qx*/
290 81363 : move32();
291 : }
292 :
293 120850 : pos = L_add( pos, shift ); /*Q16*/
294 120850 : idx = s_max( 0, extract_h( pos ) ); /*Q0*/
295 :
296 120850 : n = sub( bufferNewSize, 1 );
297 28042524 : FOR( i = 1; i < n; i++ )
298 : {
299 27921674 : diff = lshr( extract_l( pos ), 1 );
300 27921674 : if ( pos < 0 )
301 : {
302 12865 : diff = sub( 16384 /*0.5f Q15*/, diff ); /*Q15*/
303 : }
304 27921674 : *ptr++ = L_add_sat( f[idx], L_sub( Mpy_32_16_1( f[idx + 1], diff ), Mpy_32_16_1( f[idx], diff ) ) ); /*Qx*/
305 27921674 : move32();
306 27921674 : pos = L_add( pos, shift ); /*Q16*/
307 27921674 : idx = extract_h( pos );
308 : }
309 :
310 : /* last point */
311 :
312 120850 : if ( GT_32( pos, L_deposit_h( sub( bufferOldSize, 1 ) ) ) )
313 : {
314 39487 : idx = sub( bufferOldSize, 2 );
315 : }
316 120850 : assert( idx <= 2 * L_FRAME_MAX );
317 :
318 : /* diff = t - point;*/
319 120850 : diff = lshr( extract_l( L_shr( L_sub( pos, L_deposit_h( idx ) ), 1 ) ), 1 ); /*Q15*/
320 :
321 120850 : *ptr++ = L_add_sat( f[idx], L_shl_sat( Mpy_32_16_1( L_sub( f[( idx + 1 )], f[idx] ), diff ), 1 ) ); /*Qx*/
322 120850 : move32();
323 120850 : test();
324 120850 : test();
325 120850 : test();
326 120850 : IF( ( ( f <= f_out ) && ( f + bufferOldSize >= f_out ) ) || ( ( f_out <= f ) && ( f_out + bufferNewSize >= f ) ) )
327 : {
328 38806 : Copy32( buf, f_out, bufferNewSize ); /*Qx*/
329 : }
330 : }
331 :
332 :
333 : static void L_lerp_proc_fx( const Word32 *f_fx, Word32 *f_out_fx, const Word16 bufferNewSize, const Word16 bufferOldSize );
334 :
335 : /*-------------------------------------------------------------*
336 : * procedure lerp() *
337 : * *
338 : * *
339 : *-------------------------------------------------------------*/
340 :
341 65054 : void L_lerp_fx( Word32 *f /*q*/, Word32 *f_out /*q*/, Word16 bufferNewSize /*Q0*/, Word16 bufferOldSize /*Q0*/, Word16 *q )
342 : {
343 : Word16 tmpNewSize;
344 : Word16 tmp1, tmp2, tmp_e;
345 65054 : tmp1 = BASOP_Util_Divide1616_Scale( bufferNewSize, bufferOldSize, &tmp_e ); /*Q15 - tmp_e*/
346 65054 : tmp1 = shr( tmp1, sub( 15, tmp_e ) ); /*Q0*/
347 :
348 65054 : tmp2 = BASOP_Util_Divide1616_Scale( bufferOldSize, bufferNewSize, &tmp_e ); /*Q15 - tmp_e*/
349 65054 : tmp2 = shr( tmp2, sub( 15, tmp_e ) ); /*Q0*/
350 65054 : Word16 guard_bits = add( s_max( tmp1, tmp2 ), 1 );
351 65054 : IF( LT_16( getScaleFactor32( f, bufferOldSize ), guard_bits ) )
352 : {
353 62062 : *q = sub( *q, guard_bits );
354 16643770 : FOR( Word16 ind = 0; ind < bufferOldSize; ind++ )
355 : {
356 16581708 : f[ind] = L_shr( f[ind], guard_bits ); /*Q(guard_bits)*/
357 16581708 : move32();
358 : }
359 : }
360 :
361 65054 : IF( GT_32( L_mult0( 128, bufferNewSize ), L_mult0( bufferOldSize, 507 ) ) )
362 : {
363 0 : tmpNewSize = shl( bufferOldSize, 1 ); /*Q0*/
364 0 : WHILE( GT_16( bufferNewSize, bufferOldSize ) )
365 : {
366 0 : if ( LE_32( L_mult0( 128, bufferNewSize ), L_mult0( bufferOldSize, 507 ) ) )
367 : {
368 0 : tmpNewSize = bufferNewSize; /*Q0*/
369 0 : move16();
370 : }
371 :
372 0 : L_lerp_proc_fx( f, f_out, tmpNewSize, bufferOldSize );
373 :
374 0 : f = f_out;
375 0 : bufferOldSize = tmpNewSize; /*Q0*/
376 0 : move16();
377 0 : tmpNewSize = shl( tmpNewSize, 1 ); /*Q0*/
378 : }
379 : }
380 65054 : ELSE IF( GT_32( L_mult0( 128, bufferOldSize ), L_mult0( bufferNewSize, 507 ) ) )
381 : {
382 0 : tmpNewSize = shr( bufferOldSize, 1 ); /*Q0*/
383 0 : WHILE( LT_16( bufferNewSize, bufferOldSize ) )
384 : {
385 0 : if ( LE_32( L_mult0( 128, bufferOldSize ), L_mult0( bufferNewSize, 507 ) ) )
386 : {
387 0 : tmpNewSize = bufferNewSize; /*Q0*/
388 0 : move16();
389 : }
390 :
391 0 : L_lerp_proc_fx( f, f_out, tmpNewSize, bufferOldSize );
392 :
393 0 : f = f_out; /*q*/
394 0 : bufferOldSize = tmpNewSize; /*Q0*/
395 0 : move16();
396 0 : tmpNewSize = shr( tmpNewSize, 1 ); /*Q0*/
397 : }
398 : }
399 : ELSE
400 : {
401 65054 : L_lerp_proc_fx( f, f_out, bufferNewSize, bufferOldSize );
402 : }
403 :
404 65054 : return;
405 : }
406 157854 : void L_lerp_fx_q11( Word32 *f /*Q11*/, Word32 *f_out /*Q11*/, Word16 bufferNewSize /*Q0*/, Word16 bufferOldSize /*Q0*/ )
407 : {
408 : Word16 tmpNewSize;
409 :
410 157854 : IF( GT_32( L_mult0( 128, bufferNewSize ), L_mult0( bufferOldSize, 507 ) ) )
411 : {
412 0 : tmpNewSize = shl( bufferOldSize, 1 ); /*Q0*/
413 0 : WHILE( GT_16( bufferNewSize, bufferOldSize ) )
414 : {
415 0 : if ( LE_32( L_mult0( 128, bufferNewSize ), L_mult0( bufferOldSize, 507 ) ) )
416 : {
417 0 : tmpNewSize = bufferNewSize; /*Q0*/
418 0 : move16();
419 : }
420 :
421 0 : lerp_proc32( f, f_out, tmpNewSize, bufferOldSize );
422 :
423 0 : f = f_out; /*Q11*/
424 0 : bufferOldSize = tmpNewSize; /*Q0*/
425 0 : move16();
426 0 : tmpNewSize = shl( tmpNewSize, 1 ); /*Q0*/
427 : }
428 : }
429 157854 : ELSE IF( GT_32( L_mult0( 128, bufferOldSize ), L_mult0( bufferNewSize, 507 ) ) )
430 : {
431 0 : tmpNewSize = shr( bufferOldSize, 1 ); /*Q0*/
432 0 : WHILE( LT_16( bufferNewSize, bufferOldSize ) )
433 : {
434 0 : if ( LE_32( L_mult0( 128, bufferOldSize ), L_mult0( bufferNewSize, 507 ) ) )
435 : {
436 0 : tmpNewSize = bufferNewSize; /*Q0*/
437 0 : move16();
438 : }
439 :
440 0 : lerp_proc32( f, f_out, tmpNewSize, bufferOldSize );
441 :
442 0 : f = f_out;
443 0 : bufferOldSize = tmpNewSize; /*Q0*/
444 0 : move16();
445 0 : tmpNewSize = shr( tmpNewSize, 1 ); /*Q0*/
446 : }
447 : }
448 : ELSE
449 : {
450 157854 : lerp_proc32( f, f_out, bufferNewSize, bufferOldSize );
451 : }
452 :
453 157854 : return;
454 : }
455 :
456 : /*-------------------------------------------------------------*
457 : * procedure lerp_proc() *
458 : * *
459 : * *
460 : *-------------------------------------------------------------*/
461 65054 : static void L_lerp_proc_fx(
462 : const Word32 *f_fx, /*Qx*/
463 : Word32 *f_out_fx, /*Qx*/
464 : const Word16 bufferNewSize, /*Q0*/
465 : const Word16 bufferOldSize /*Q0*/ )
466 : {
467 : Word16 i, idx;
468 : Word32 pos_fx, shift_fx, diff_fx;
469 : Word32 buf_fx[2 * L_FRAME_MAX];
470 : Word16 tmp;
471 : Word32 ffxsub;
472 :
473 65054 : IF( EQ_16( bufferNewSize, bufferOldSize ) )
474 : {
475 12 : Copy32( f_fx, buf_fx, bufferNewSize ); /*Qx*/
476 12 : Copy32( buf_fx, f_out_fx, bufferNewSize ); /*Qx*/
477 12 : return;
478 : }
479 :
480 : /* Using the basop code to avoid reading beyond end of input for bufferOldSize=320, bufferNewSize=640 */
481 65042 : tmp = div_s( bufferOldSize, shl( bufferNewSize, 4 ) ); /*Q11*/
482 65042 : shift_fx = L_shl( L_deposit_l( tmp ), 4 - 15 + 21 ); // q =21
483 65042 : pos_fx = Mpy_32_32( L_sub( shift_fx, 1 << 21 ), ONE_IN_Q30 /*0.5f in Q31*/ ); /*Q21*/
484 :
485 65042 : IF( LT_32( shift_fx, L_shr( 644245094 /*0.3 in Q31*/, 31 - 21 ) ) )
486 : {
487 0 : pos_fx = L_sub( pos_fx, L_shr( 279172874 /*0.13 in Q31*/, 31 - 21 ) ); /*Q21*/
488 : }
489 :
490 : /* first point of interpolation */
491 65042 : IF( pos_fx < 0 )
492 : {
493 3922 : buf_fx[0] = L_add( f_fx[0], L_shl( Mpy_32_32( pos_fx, L_sub( f_fx[1], f_fx[0] ) ), 31 - 21 ) ); /*Qx*/
494 3922 : move32();
495 : }
496 : ELSE
497 : {
498 61120 : idx = extract_l( L_shr( pos_fx, 21 ) );
499 :
500 61120 : diff_fx = L_sub( pos_fx, L_shl( idx, 21 ) );
501 61120 : ffxsub = L_sub( f_fx[idx + 1], f_fx[idx] );
502 :
503 61120 : Word64 f_fx64 = W_shl( f_fx[idx], 21 );
504 61120 : Word64 mult64 = W_mult0_32_32( diff_fx, ffxsub );
505 61120 : Word64 add64 = W_add( f_fx64, mult64 );
506 :
507 61120 : buf_fx[0] = W_extract_l( W_shr( add64, 21 ) );
508 61120 : move32();
509 : }
510 :
511 65042 : pos_fx = L_add( pos_fx, shift_fx ); /*Q21*/
512 :
513 9882886 : FOR( i = 1; i < bufferNewSize - 1; i++ )
514 : {
515 9817844 : idx = extract_l( L_shr( pos_fx, 21 ) );
516 9817844 : diff_fx = L_sub( pos_fx, L_shl( idx, 21 ) ); /*Q21*/
517 :
518 9817844 : ffxsub = L_sub( f_fx[idx + 1], f_fx[idx] );
519 :
520 9817844 : Word64 f_fx64 = W_shl( f_fx[idx], 21 );
521 9817844 : Word64 mult64 = W_mult0_32_32( diff_fx, ffxsub );
522 9817844 : Word64 add64 = W_add( f_fx64, mult64 );
523 :
524 9817844 : buf_fx[i] = W_extract_l( W_shr( add64, 21 ) );
525 9817844 : move32();
526 :
527 9817844 : pos_fx = L_add( pos_fx, shift_fx ); /*Q21*/
528 : }
529 :
530 :
531 : /* last point */
532 65042 : idx = extract_l( L_shr( pos_fx, 21 ) ); /*Q0*/
533 :
534 65042 : if ( GT_32( pos_fx, L_shl( sub( bufferOldSize, 1 ), 21 ) ) )
535 : {
536 2082 : idx = sub( bufferOldSize, 2 );
537 : }
538 :
539 65042 : diff_fx = L_sub( pos_fx, L_shl( idx, 21 ) ); /*Q21*/
540 :
541 65042 : buf_fx[( bufferNewSize - 1 )] = L_add( f_fx[idx], L_shl( Mpy_32_32( diff_fx, L_sub( f_fx[( idx + 1 )], f_fx[idx] ) ), 31 - 21 ) ); /*Qx*/
542 65042 : move32();
543 :
544 65042 : Copy32( buf_fx, f_out_fx, bufferNewSize ); /*Qx*/
545 :
546 65042 : return;
547 : }
|