1 /*
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11
12 /*
13 * This header file contains some internal resampling functions.
14 *
15 */
16
17 #include "resample_by_2_internal.h"
18
19 // allpass filter coefficients.
20 static const WebRtc_Word16 kResampleAllpass[2][3] = {
21 {821, 6110, 12382},
22 {3050, 9368, 15063}
23 };
24
25 //
26 // decimator
27 // input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) OVERWRITTEN!
28 // output: WebRtc_Word16 (saturated) (of length len/2)
29 // state: filter state array; length = 8
30
WebRtcSpl_DownBy2IntToShort(WebRtc_Word32 * in,WebRtc_Word32 len,WebRtc_Word16 * out,WebRtc_Word32 * state)31 void WebRtcSpl_DownBy2IntToShort(WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out,
32 WebRtc_Word32 *state)
33 {
34 WebRtc_Word32 tmp0, tmp1, diff;
35 WebRtc_Word32 i;
36
37 len >>= 1;
38
39 // lower allpass filter (operates on even input samples)
40 for (i = 0; i < len; i++)
41 {
42 tmp0 = in[i << 1];
43 diff = tmp0 - state[1];
44 // scale down and round
45 diff = (diff + (1 << 13)) >> 14;
46 tmp1 = state[0] + diff * kResampleAllpass[1][0];
47 state[0] = tmp0;
48 diff = tmp1 - state[2];
49 // scale down and truncate
50 diff = diff >> 14;
51 if (diff < 0)
52 diff += 1;
53 tmp0 = state[1] + diff * kResampleAllpass[1][1];
54 state[1] = tmp1;
55 diff = tmp0 - state[3];
56 // scale down and truncate
57 diff = diff >> 14;
58 if (diff < 0)
59 diff += 1;
60 state[3] = state[2] + diff * kResampleAllpass[1][2];
61 state[2] = tmp0;
62
63 // divide by two and store temporarily
64 in[i << 1] = (state[3] >> 1);
65 }
66
67 in++;
68
69 // upper allpass filter (operates on odd input samples)
70 for (i = 0; i < len; i++)
71 {
72 tmp0 = in[i << 1];
73 diff = tmp0 - state[5];
74 // scale down and round
75 diff = (diff + (1 << 13)) >> 14;
76 tmp1 = state[4] + diff * kResampleAllpass[0][0];
77 state[4] = tmp0;
78 diff = tmp1 - state[6];
79 // scale down and round
80 diff = diff >> 14;
81 if (diff < 0)
82 diff += 1;
83 tmp0 = state[5] + diff * kResampleAllpass[0][1];
84 state[5] = tmp1;
85 diff = tmp0 - state[7];
86 // scale down and truncate
87 diff = diff >> 14;
88 if (diff < 0)
89 diff += 1;
90 state[7] = state[6] + diff * kResampleAllpass[0][2];
91 state[6] = tmp0;
92
93 // divide by two and store temporarily
94 in[i << 1] = (state[7] >> 1);
95 }
96
97 in--;
98
99 // combine allpass outputs
100 for (i = 0; i < len; i += 2)
101 {
102 // divide by two, add both allpass outputs and round
103 tmp0 = (in[i << 1] + in[(i << 1) + 1]) >> 15;
104 tmp1 = (in[(i << 1) + 2] + in[(i << 1) + 3]) >> 15;
105 if (tmp0 > (WebRtc_Word32)0x00007FFF)
106 tmp0 = 0x00007FFF;
107 if (tmp0 < (WebRtc_Word32)0xFFFF8000)
108 tmp0 = 0xFFFF8000;
109 out[i] = (WebRtc_Word16)tmp0;
110 if (tmp1 > (WebRtc_Word32)0x00007FFF)
111 tmp1 = 0x00007FFF;
112 if (tmp1 < (WebRtc_Word32)0xFFFF8000)
113 tmp1 = 0xFFFF8000;
114 out[i + 1] = (WebRtc_Word16)tmp1;
115 }
116 }
117
118 //
119 // decimator
120 // input: WebRtc_Word16
121 // output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) (of length len/2)
122 // state: filter state array; length = 8
123
WebRtcSpl_DownBy2ShortToInt(const WebRtc_Word16 * in,WebRtc_Word32 len,WebRtc_Word32 * out,WebRtc_Word32 * state)124 void WebRtcSpl_DownBy2ShortToInt(const WebRtc_Word16 *in,
125 WebRtc_Word32 len,
126 WebRtc_Word32 *out,
127 WebRtc_Word32 *state)
128 {
129 WebRtc_Word32 tmp0, tmp1, diff;
130 WebRtc_Word32 i;
131
132 len >>= 1;
133
134 // lower allpass filter (operates on even input samples)
135 for (i = 0; i < len; i++)
136 {
137 tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
138 diff = tmp0 - state[1];
139 // scale down and round
140 diff = (diff + (1 << 13)) >> 14;
141 tmp1 = state[0] + diff * kResampleAllpass[1][0];
142 state[0] = tmp0;
143 diff = tmp1 - state[2];
144 // scale down and truncate
145 diff = diff >> 14;
146 if (diff < 0)
147 diff += 1;
148 tmp0 = state[1] + diff * kResampleAllpass[1][1];
149 state[1] = tmp1;
150 diff = tmp0 - state[3];
151 // scale down and truncate
152 diff = diff >> 14;
153 if (diff < 0)
154 diff += 1;
155 state[3] = state[2] + diff * kResampleAllpass[1][2];
156 state[2] = tmp0;
157
158 // divide by two and store temporarily
159 out[i] = (state[3] >> 1);
160 }
161
162 in++;
163
164 // upper allpass filter (operates on odd input samples)
165 for (i = 0; i < len; i++)
166 {
167 tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
168 diff = tmp0 - state[5];
169 // scale down and round
170 diff = (diff + (1 << 13)) >> 14;
171 tmp1 = state[4] + diff * kResampleAllpass[0][0];
172 state[4] = tmp0;
173 diff = tmp1 - state[6];
174 // scale down and round
175 diff = diff >> 14;
176 if (diff < 0)
177 diff += 1;
178 tmp0 = state[5] + diff * kResampleAllpass[0][1];
179 state[5] = tmp1;
180 diff = tmp0 - state[7];
181 // scale down and truncate
182 diff = diff >> 14;
183 if (diff < 0)
184 diff += 1;
185 state[7] = state[6] + diff * kResampleAllpass[0][2];
186 state[6] = tmp0;
187
188 // divide by two and store temporarily
189 out[i] += (state[7] >> 1);
190 }
191
192 in--;
193 }
194
195 //
196 // interpolator
197 // input: WebRtc_Word16
198 // output: WebRtc_Word32 (normalized, not saturated) (of length len*2)
199 // state: filter state array; length = 8
WebRtcSpl_UpBy2ShortToInt(const WebRtc_Word16 * in,WebRtc_Word32 len,WebRtc_Word32 * out,WebRtc_Word32 * state)200 void WebRtcSpl_UpBy2ShortToInt(const WebRtc_Word16 *in, WebRtc_Word32 len, WebRtc_Word32 *out,
201 WebRtc_Word32 *state)
202 {
203 WebRtc_Word32 tmp0, tmp1, diff;
204 WebRtc_Word32 i;
205
206 // upper allpass filter (generates odd output samples)
207 for (i = 0; i < len; i++)
208 {
209 tmp0 = ((WebRtc_Word32)in[i] << 15) + (1 << 14);
210 diff = tmp0 - state[5];
211 // scale down and round
212 diff = (diff + (1 << 13)) >> 14;
213 tmp1 = state[4] + diff * kResampleAllpass[0][0];
214 state[4] = tmp0;
215 diff = tmp1 - state[6];
216 // scale down and truncate
217 diff = diff >> 14;
218 if (diff < 0)
219 diff += 1;
220 tmp0 = state[5] + diff * kResampleAllpass[0][1];
221 state[5] = tmp1;
222 diff = tmp0 - state[7];
223 // scale down and truncate
224 diff = diff >> 14;
225 if (diff < 0)
226 diff += 1;
227 state[7] = state[6] + diff * kResampleAllpass[0][2];
228 state[6] = tmp0;
229
230 // scale down, round and store
231 out[i << 1] = state[7] >> 15;
232 }
233
234 out++;
235
236 // lower allpass filter (generates even output samples)
237 for (i = 0; i < len; i++)
238 {
239 tmp0 = ((WebRtc_Word32)in[i] << 15) + (1 << 14);
240 diff = tmp0 - state[1];
241 // scale down and round
242 diff = (diff + (1 << 13)) >> 14;
243 tmp1 = state[0] + diff * kResampleAllpass[1][0];
244 state[0] = tmp0;
245 diff = tmp1 - state[2];
246 // scale down and truncate
247 diff = diff >> 14;
248 if (diff < 0)
249 diff += 1;
250 tmp0 = state[1] + diff * kResampleAllpass[1][1];
251 state[1] = tmp1;
252 diff = tmp0 - state[3];
253 // scale down and truncate
254 diff = diff >> 14;
255 if (diff < 0)
256 diff += 1;
257 state[3] = state[2] + diff * kResampleAllpass[1][2];
258 state[2] = tmp0;
259
260 // scale down, round and store
261 out[i << 1] = state[3] >> 15;
262 }
263 }
264
265 //
266 // interpolator
267 // input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384)
268 // output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) (of length len*2)
269 // state: filter state array; length = 8
WebRtcSpl_UpBy2IntToInt(const WebRtc_Word32 * in,WebRtc_Word32 len,WebRtc_Word32 * out,WebRtc_Word32 * state)270 void WebRtcSpl_UpBy2IntToInt(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word32 *out,
271 WebRtc_Word32 *state)
272 {
273 WebRtc_Word32 tmp0, tmp1, diff;
274 WebRtc_Word32 i;
275
276 // upper allpass filter (generates odd output samples)
277 for (i = 0; i < len; i++)
278 {
279 tmp0 = in[i];
280 diff = tmp0 - state[5];
281 // scale down and round
282 diff = (diff + (1 << 13)) >> 14;
283 tmp1 = state[4] + diff * kResampleAllpass[0][0];
284 state[4] = tmp0;
285 diff = tmp1 - state[6];
286 // scale down and truncate
287 diff = diff >> 14;
288 if (diff < 0)
289 diff += 1;
290 tmp0 = state[5] + diff * kResampleAllpass[0][1];
291 state[5] = tmp1;
292 diff = tmp0 - state[7];
293 // scale down and truncate
294 diff = diff >> 14;
295 if (diff < 0)
296 diff += 1;
297 state[7] = state[6] + diff * kResampleAllpass[0][2];
298 state[6] = tmp0;
299
300 // scale down, round and store
301 out[i << 1] = state[7];
302 }
303
304 out++;
305
306 // lower allpass filter (generates even output samples)
307 for (i = 0; i < len; i++)
308 {
309 tmp0 = in[i];
310 diff = tmp0 - state[1];
311 // scale down and round
312 diff = (diff + (1 << 13)) >> 14;
313 tmp1 = state[0] + diff * kResampleAllpass[1][0];
314 state[0] = tmp0;
315 diff = tmp1 - state[2];
316 // scale down and truncate
317 diff = diff >> 14;
318 if (diff < 0)
319 diff += 1;
320 tmp0 = state[1] + diff * kResampleAllpass[1][1];
321 state[1] = tmp1;
322 diff = tmp0 - state[3];
323 // scale down and truncate
324 diff = diff >> 14;
325 if (diff < 0)
326 diff += 1;
327 state[3] = state[2] + diff * kResampleAllpass[1][2];
328 state[2] = tmp0;
329
330 // scale down, round and store
331 out[i << 1] = state[3];
332 }
333 }
334
335 //
336 // interpolator
337 // input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384)
338 // output: WebRtc_Word16 (saturated) (of length len*2)
339 // state: filter state array; length = 8
WebRtcSpl_UpBy2IntToShort(const WebRtc_Word32 * in,WebRtc_Word32 len,WebRtc_Word16 * out,WebRtc_Word32 * state)340 void WebRtcSpl_UpBy2IntToShort(const WebRtc_Word32 *in, WebRtc_Word32 len, WebRtc_Word16 *out,
341 WebRtc_Word32 *state)
342 {
343 WebRtc_Word32 tmp0, tmp1, diff;
344 WebRtc_Word32 i;
345
346 // upper allpass filter (generates odd output samples)
347 for (i = 0; i < len; i++)
348 {
349 tmp0 = in[i];
350 diff = tmp0 - state[5];
351 // scale down and round
352 diff = (diff + (1 << 13)) >> 14;
353 tmp1 = state[4] + diff * kResampleAllpass[0][0];
354 state[4] = tmp0;
355 diff = tmp1 - state[6];
356 // scale down and round
357 diff = diff >> 14;
358 if (diff < 0)
359 diff += 1;
360 tmp0 = state[5] + diff * kResampleAllpass[0][1];
361 state[5] = tmp1;
362 diff = tmp0 - state[7];
363 // scale down and truncate
364 diff = diff >> 14;
365 if (diff < 0)
366 diff += 1;
367 state[7] = state[6] + diff * kResampleAllpass[0][2];
368 state[6] = tmp0;
369
370 // scale down, saturate and store
371 tmp1 = state[7] >> 15;
372 if (tmp1 > (WebRtc_Word32)0x00007FFF)
373 tmp1 = 0x00007FFF;
374 if (tmp1 < (WebRtc_Word32)0xFFFF8000)
375 tmp1 = 0xFFFF8000;
376 out[i << 1] = (WebRtc_Word16)tmp1;
377 }
378
379 out++;
380
381 // lower allpass filter (generates even output samples)
382 for (i = 0; i < len; i++)
383 {
384 tmp0 = in[i];
385 diff = tmp0 - state[1];
386 // scale down and round
387 diff = (diff + (1 << 13)) >> 14;
388 tmp1 = state[0] + diff * kResampleAllpass[1][0];
389 state[0] = tmp0;
390 diff = tmp1 - state[2];
391 // scale down and truncate
392 diff = diff >> 14;
393 if (diff < 0)
394 diff += 1;
395 tmp0 = state[1] + diff * kResampleAllpass[1][1];
396 state[1] = tmp1;
397 diff = tmp0 - state[3];
398 // scale down and truncate
399 diff = diff >> 14;
400 if (diff < 0)
401 diff += 1;
402 state[3] = state[2] + diff * kResampleAllpass[1][2];
403 state[2] = tmp0;
404
405 // scale down, saturate and store
406 tmp1 = state[3] >> 15;
407 if (tmp1 > (WebRtc_Word32)0x00007FFF)
408 tmp1 = 0x00007FFF;
409 if (tmp1 < (WebRtc_Word32)0xFFFF8000)
410 tmp1 = 0xFFFF8000;
411 out[i << 1] = (WebRtc_Word16)tmp1;
412 }
413 }
414
415 // lowpass filter
416 // input: WebRtc_Word16
417 // output: WebRtc_Word32 (normalized, not saturated)
418 // state: filter state array; length = 8
WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16 * in,WebRtc_Word32 len,WebRtc_Word32 * out,WebRtc_Word32 * state)419 void WebRtcSpl_LPBy2ShortToInt(const WebRtc_Word16* in, WebRtc_Word32 len, WebRtc_Word32* out,
420 WebRtc_Word32* state)
421 {
422 WebRtc_Word32 tmp0, tmp1, diff;
423 WebRtc_Word32 i;
424
425 len >>= 1;
426
427 // lower allpass filter: odd input -> even output samples
428 in++;
429 // initial state of polyphase delay element
430 tmp0 = state[12];
431 for (i = 0; i < len; i++)
432 {
433 diff = tmp0 - state[1];
434 // scale down and round
435 diff = (diff + (1 << 13)) >> 14;
436 tmp1 = state[0] + diff * kResampleAllpass[1][0];
437 state[0] = tmp0;
438 diff = tmp1 - state[2];
439 // scale down and truncate
440 diff = diff >> 14;
441 if (diff < 0)
442 diff += 1;
443 tmp0 = state[1] + diff * kResampleAllpass[1][1];
444 state[1] = tmp1;
445 diff = tmp0 - state[3];
446 // scale down and truncate
447 diff = diff >> 14;
448 if (diff < 0)
449 diff += 1;
450 state[3] = state[2] + diff * kResampleAllpass[1][2];
451 state[2] = tmp0;
452
453 // scale down, round and store
454 out[i << 1] = state[3] >> 1;
455 tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
456 }
457 in--;
458
459 // upper allpass filter: even input -> even output samples
460 for (i = 0; i < len; i++)
461 {
462 tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
463 diff = tmp0 - state[5];
464 // scale down and round
465 diff = (diff + (1 << 13)) >> 14;
466 tmp1 = state[4] + diff * kResampleAllpass[0][0];
467 state[4] = tmp0;
468 diff = tmp1 - state[6];
469 // scale down and round
470 diff = diff >> 14;
471 if (diff < 0)
472 diff += 1;
473 tmp0 = state[5] + diff * kResampleAllpass[0][1];
474 state[5] = tmp1;
475 diff = tmp0 - state[7];
476 // scale down and truncate
477 diff = diff >> 14;
478 if (diff < 0)
479 diff += 1;
480 state[7] = state[6] + diff * kResampleAllpass[0][2];
481 state[6] = tmp0;
482
483 // average the two allpass outputs, scale down and store
484 out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15;
485 }
486
487 // switch to odd output samples
488 out++;
489
490 // lower allpass filter: even input -> odd output samples
491 for (i = 0; i < len; i++)
492 {
493 tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
494 diff = tmp0 - state[9];
495 // scale down and round
496 diff = (diff + (1 << 13)) >> 14;
497 tmp1 = state[8] + diff * kResampleAllpass[1][0];
498 state[8] = tmp0;
499 diff = tmp1 - state[10];
500 // scale down and truncate
501 diff = diff >> 14;
502 if (diff < 0)
503 diff += 1;
504 tmp0 = state[9] + diff * kResampleAllpass[1][1];
505 state[9] = tmp1;
506 diff = tmp0 - state[11];
507 // scale down and truncate
508 diff = diff >> 14;
509 if (diff < 0)
510 diff += 1;
511 state[11] = state[10] + diff * kResampleAllpass[1][2];
512 state[10] = tmp0;
513
514 // scale down, round and store
515 out[i << 1] = state[11] >> 1;
516 }
517
518 // upper allpass filter: odd input -> odd output samples
519 in++;
520 for (i = 0; i < len; i++)
521 {
522 tmp0 = ((WebRtc_Word32)in[i << 1] << 15) + (1 << 14);
523 diff = tmp0 - state[13];
524 // scale down and round
525 diff = (diff + (1 << 13)) >> 14;
526 tmp1 = state[12] + diff * kResampleAllpass[0][0];
527 state[12] = tmp0;
528 diff = tmp1 - state[14];
529 // scale down and round
530 diff = diff >> 14;
531 if (diff < 0)
532 diff += 1;
533 tmp0 = state[13] + diff * kResampleAllpass[0][1];
534 state[13] = tmp1;
535 diff = tmp0 - state[15];
536 // scale down and truncate
537 diff = diff >> 14;
538 if (diff < 0)
539 diff += 1;
540 state[15] = state[14] + diff * kResampleAllpass[0][2];
541 state[14] = tmp0;
542
543 // average the two allpass outputs, scale down and store
544 out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15;
545 }
546 }
547
548 // lowpass filter
549 // input: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384)
550 // output: WebRtc_Word32 (normalized, not saturated)
551 // state: filter state array; length = 8
WebRtcSpl_LPBy2IntToInt(const WebRtc_Word32 * in,WebRtc_Word32 len,WebRtc_Word32 * out,WebRtc_Word32 * state)552 void WebRtcSpl_LPBy2IntToInt(const WebRtc_Word32* in, WebRtc_Word32 len, WebRtc_Word32* out,
553 WebRtc_Word32* state)
554 {
555 WebRtc_Word32 tmp0, tmp1, diff;
556 WebRtc_Word32 i;
557
558 len >>= 1;
559
560 // lower allpass filter: odd input -> even output samples
561 in++;
562 // initial state of polyphase delay element
563 tmp0 = state[12];
564 for (i = 0; i < len; i++)
565 {
566 diff = tmp0 - state[1];
567 // scale down and round
568 diff = (diff + (1 << 13)) >> 14;
569 tmp1 = state[0] + diff * kResampleAllpass[1][0];
570 state[0] = tmp0;
571 diff = tmp1 - state[2];
572 // scale down and truncate
573 diff = diff >> 14;
574 if (diff < 0)
575 diff += 1;
576 tmp0 = state[1] + diff * kResampleAllpass[1][1];
577 state[1] = tmp1;
578 diff = tmp0 - state[3];
579 // scale down and truncate
580 diff = diff >> 14;
581 if (diff < 0)
582 diff += 1;
583 state[3] = state[2] + diff * kResampleAllpass[1][2];
584 state[2] = tmp0;
585
586 // scale down, round and store
587 out[i << 1] = state[3] >> 1;
588 tmp0 = in[i << 1];
589 }
590 in--;
591
592 // upper allpass filter: even input -> even output samples
593 for (i = 0; i < len; i++)
594 {
595 tmp0 = in[i << 1];
596 diff = tmp0 - state[5];
597 // scale down and round
598 diff = (diff + (1 << 13)) >> 14;
599 tmp1 = state[4] + diff * kResampleAllpass[0][0];
600 state[4] = tmp0;
601 diff = tmp1 - state[6];
602 // scale down and round
603 diff = diff >> 14;
604 if (diff < 0)
605 diff += 1;
606 tmp0 = state[5] + diff * kResampleAllpass[0][1];
607 state[5] = tmp1;
608 diff = tmp0 - state[7];
609 // scale down and truncate
610 diff = diff >> 14;
611 if (diff < 0)
612 diff += 1;
613 state[7] = state[6] + diff * kResampleAllpass[0][2];
614 state[6] = tmp0;
615
616 // average the two allpass outputs, scale down and store
617 out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15;
618 }
619
620 // switch to odd output samples
621 out++;
622
623 // lower allpass filter: even input -> odd output samples
624 for (i = 0; i < len; i++)
625 {
626 tmp0 = in[i << 1];
627 diff = tmp0 - state[9];
628 // scale down and round
629 diff = (diff + (1 << 13)) >> 14;
630 tmp1 = state[8] + diff * kResampleAllpass[1][0];
631 state[8] = tmp0;
632 diff = tmp1 - state[10];
633 // scale down and truncate
634 diff = diff >> 14;
635 if (diff < 0)
636 diff += 1;
637 tmp0 = state[9] + diff * kResampleAllpass[1][1];
638 state[9] = tmp1;
639 diff = tmp0 - state[11];
640 // scale down and truncate
641 diff = diff >> 14;
642 if (diff < 0)
643 diff += 1;
644 state[11] = state[10] + diff * kResampleAllpass[1][2];
645 state[10] = tmp0;
646
647 // scale down, round and store
648 out[i << 1] = state[11] >> 1;
649 }
650
651 // upper allpass filter: odd input -> odd output samples
652 in++;
653 for (i = 0; i < len; i++)
654 {
655 tmp0 = in[i << 1];
656 diff = tmp0 - state[13];
657 // scale down and round
658 diff = (diff + (1 << 13)) >> 14;
659 tmp1 = state[12] + diff * kResampleAllpass[0][0];
660 state[12] = tmp0;
661 diff = tmp1 - state[14];
662 // scale down and round
663 diff = diff >> 14;
664 if (diff < 0)
665 diff += 1;
666 tmp0 = state[13] + diff * kResampleAllpass[0][1];
667 state[13] = tmp1;
668 diff = tmp0 - state[15];
669 // scale down and truncate
670 diff = diff >> 14;
671 if (diff < 0)
672 diff += 1;
673 state[15] = state[14] + diff * kResampleAllpass[0][2];
674 state[14] = tmp0;
675
676 // average the two allpass outputs, scale down and store
677 out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15;
678 }
679 }
680