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