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