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