| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 | 11 |
| 12 /* | 12 /* |
| 13 * This header file contains some internal resampling functions. | 13 * This header file contains some internal resampling functions. |
| 14 * | 14 * |
| 15 */ | 15 */ |
| 16 | 16 |
| 17 #include "webrtc/common_audio/signal_processing/resample_by_2_internal.h" | 17 #include "webrtc/common_audio/signal_processing/resample_by_2_internal.h" |
| 18 #include "webrtc/rtc_base/sanitizer.h" |
| 18 | 19 |
| 19 // allpass filter coefficients. | 20 // allpass filter coefficients. |
| 20 static const int16_t kResampleAllpass[2][3] = { | 21 static const int16_t kResampleAllpass[2][3] = { |
| 21 {821, 6110, 12382}, | 22 {821, 6110, 12382}, |
| 22 {3050, 9368, 15063} | 23 {3050, 9368, 15063} |
| 23 }; | 24 }; |
| 24 | 25 |
| 25 // | 26 // |
| 26 // decimator | 27 // decimator |
| 27 // input: int32_t (shifted 15 positions to the left, + offset 16384) OVERWRITTE
N! | 28 // input: int32_t (shifted 15 positions to the left, + offset 16384) OVERWRITTE
N! |
| 28 // output: int16_t (saturated) (of length len/2) | 29 // output: int16_t (saturated) (of length len/2) |
| 29 // state: filter state array; length = 8 | 30 // state: filter state array; length = 8 |
| 30 | 31 |
| 31 void WebRtcSpl_DownBy2IntToShort(int32_t *in, int32_t len, int16_t *out, | 32 void RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/5486 |
| 32 int32_t *state) | 33 WebRtcSpl_DownBy2IntToShort(int32_t *in, int32_t len, int16_t *out, |
| 34 int32_t *state) |
| 33 { | 35 { |
| 34 int32_t tmp0, tmp1, diff; | 36 int32_t tmp0, tmp1, diff; |
| 35 int32_t i; | 37 int32_t i; |
| 36 | 38 |
| 37 len >>= 1; | 39 len >>= 1; |
| 38 | 40 |
| 39 // lower allpass filter (operates on even input samples) | 41 // lower allpass filter (operates on even input samples) |
| 40 for (i = 0; i < len; i++) | 42 for (i = 0; i < len; i++) |
| 41 { | 43 { |
| 42 tmp0 = in[i << 1]; | 44 tmp0 = in[i << 1]; |
| 43 diff = tmp0 - state[1]; | 45 diff = tmp0 - state[1]; |
| 46 // UBSan: -1771017321 - 999586185 cannot be represented in type 'int' |
| 47 |
| 44 // scale down and round | 48 // scale down and round |
| 45 diff = (diff + (1 << 13)) >> 14; | 49 diff = (diff + (1 << 13)) >> 14; |
| 46 tmp1 = state[0] + diff * kResampleAllpass[1][0]; | 50 tmp1 = state[0] + diff * kResampleAllpass[1][0]; |
| 47 state[0] = tmp0; | 51 state[0] = tmp0; |
| 48 diff = tmp1 - state[2]; | 52 diff = tmp1 - state[2]; |
| 49 // scale down and truncate | 53 // scale down and truncate |
| 50 diff = diff >> 14; | 54 diff = diff >> 14; |
| 51 if (diff < 0) | 55 if (diff < 0) |
| 52 diff += 1; | 56 diff += 1; |
| 53 tmp0 = state[1] + diff * kResampleAllpass[1][1]; | 57 tmp0 = state[1] + diff * kResampleAllpass[1][1]; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 out[i + 1] = (int16_t)tmp1; | 118 out[i + 1] = (int16_t)tmp1; |
| 115 } | 119 } |
| 116 } | 120 } |
| 117 | 121 |
| 118 // | 122 // |
| 119 // decimator | 123 // decimator |
| 120 // input: int16_t | 124 // input: int16_t |
| 121 // output: int32_t (shifted 15 positions to the left, + offset 16384) (of length
len/2) | 125 // output: int32_t (shifted 15 positions to the left, + offset 16384) (of length
len/2) |
| 122 // state: filter state array; length = 8 | 126 // state: filter state array; length = 8 |
| 123 | 127 |
| 124 void WebRtcSpl_DownBy2ShortToInt(const int16_t *in, | 128 void RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/5486 |
| 125 int32_t len, | 129 WebRtcSpl_DownBy2ShortToInt(const int16_t *in, |
| 126 int32_t *out, | 130 int32_t len, |
| 127 int32_t *state) | 131 int32_t *out, |
| 132 int32_t *state) |
| 128 { | 133 { |
| 129 int32_t tmp0, tmp1, diff; | 134 int32_t tmp0, tmp1, diff; |
| 130 int32_t i; | 135 int32_t i; |
| 131 | 136 |
| 132 len >>= 1; | 137 len >>= 1; |
| 133 | 138 |
| 134 // lower allpass filter (operates on even input samples) | 139 // lower allpass filter (operates on even input samples) |
| 135 for (i = 0; i < len; i++) | 140 for (i = 0; i < len; i++) |
| 136 { | 141 { |
| 137 tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); | 142 tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); |
| 138 diff = tmp0 - state[1]; | 143 diff = tmp0 - state[1]; |
| 139 // scale down and round | 144 // scale down and round |
| 140 diff = (diff + (1 << 13)) >> 14; | 145 diff = (diff + (1 << 13)) >> 14; |
| 141 tmp1 = state[0] + diff * kResampleAllpass[1][0]; | 146 tmp1 = state[0] + diff * kResampleAllpass[1][0]; |
| 142 state[0] = tmp0; | 147 state[0] = tmp0; |
| 143 diff = tmp1 - state[2]; | 148 diff = tmp1 - state[2]; |
| 149 // UBSan: -1379909682 - 834099714 cannot be represented in type 'int' |
| 150 |
| 144 // scale down and truncate | 151 // scale down and truncate |
| 145 diff = diff >> 14; | 152 diff = diff >> 14; |
| 146 if (diff < 0) | 153 if (diff < 0) |
| 147 diff += 1; | 154 diff += 1; |
| 148 tmp0 = state[1] + diff * kResampleAllpass[1][1]; | 155 tmp0 = state[1] + diff * kResampleAllpass[1][1]; |
| 149 state[1] = tmp1; | 156 state[1] = tmp1; |
| 150 diff = tmp0 - state[3]; | 157 diff = tmp0 - state[3]; |
| 151 // scale down and truncate | 158 // scale down and truncate |
| 152 diff = diff >> 14; | 159 diff = diff >> 14; |
| 153 if (diff < 0) | 160 if (diff < 0) |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 | 549 |
| 543 // average the two allpass outputs, scale down and store | 550 // average the two allpass outputs, scale down and store |
| 544 out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15; | 551 out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15; |
| 545 } | 552 } |
| 546 } | 553 } |
| 547 | 554 |
| 548 // lowpass filter | 555 // lowpass filter |
| 549 // input: int32_t (shifted 15 positions to the left, + offset 16384) | 556 // input: int32_t (shifted 15 positions to the left, + offset 16384) |
| 550 // output: int32_t (normalized, not saturated) | 557 // output: int32_t (normalized, not saturated) |
| 551 // state: filter state array; length = 8 | 558 // state: filter state array; length = 8 |
| 552 void WebRtcSpl_LPBy2IntToInt(const int32_t* in, int32_t len, int32_t* out, | 559 void RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/5486 |
| 553 int32_t* state) | 560 WebRtcSpl_LPBy2IntToInt(const int32_t* in, int32_t len, int32_t* out, |
| 561 int32_t* state) |
| 554 { | 562 { |
| 555 int32_t tmp0, tmp1, diff; | 563 int32_t tmp0, tmp1, diff; |
| 556 int32_t i; | 564 int32_t i; |
| 557 | 565 |
| 558 len >>= 1; | 566 len >>= 1; |
| 559 | 567 |
| 560 // lower allpass filter: odd input -> even output samples | 568 // lower allpass filter: odd input -> even output samples |
| 561 in++; | 569 in++; |
| 562 // initial state of polyphase delay element | 570 // initial state of polyphase delay element |
| 563 tmp0 = state[12]; | 571 tmp0 = state[12]; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 587 out[i << 1] = state[3] >> 1; | 595 out[i << 1] = state[3] >> 1; |
| 588 tmp0 = in[i << 1]; | 596 tmp0 = in[i << 1]; |
| 589 } | 597 } |
| 590 in--; | 598 in--; |
| 591 | 599 |
| 592 // upper allpass filter: even input -> even output samples | 600 // upper allpass filter: even input -> even output samples |
| 593 for (i = 0; i < len; i++) | 601 for (i = 0; i < len; i++) |
| 594 { | 602 { |
| 595 tmp0 = in[i << 1]; | 603 tmp0 = in[i << 1]; |
| 596 diff = tmp0 - state[5]; | 604 diff = tmp0 - state[5]; |
| 605 // UBSan: -794814117 - 1566149201 cannot be represented in type 'int' |
| 606 |
| 597 // scale down and round | 607 // scale down and round |
| 598 diff = (diff + (1 << 13)) >> 14; | 608 diff = (diff + (1 << 13)) >> 14; |
| 599 tmp1 = state[4] + diff * kResampleAllpass[0][0]; | 609 tmp1 = state[4] + diff * kResampleAllpass[0][0]; |
| 600 state[4] = tmp0; | 610 state[4] = tmp0; |
| 601 diff = tmp1 - state[6]; | 611 diff = tmp1 - state[6]; |
| 602 // scale down and round | 612 // scale down and round |
| 603 diff = diff >> 14; | 613 diff = diff >> 14; |
| 604 if (diff < 0) | 614 if (diff < 0) |
| 605 diff += 1; | 615 diff += 1; |
| 606 tmp0 = state[5] + diff * kResampleAllpass[0][1]; | 616 tmp0 = state[5] + diff * kResampleAllpass[0][1]; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 diff = diff >> 14; | 680 diff = diff >> 14; |
| 671 if (diff < 0) | 681 if (diff < 0) |
| 672 diff += 1; | 682 diff += 1; |
| 673 state[15] = state[14] + diff * kResampleAllpass[0][2]; | 683 state[15] = state[14] + diff * kResampleAllpass[0][2]; |
| 674 state[14] = tmp0; | 684 state[14] = tmp0; |
| 675 | 685 |
| 676 // average the two allpass outputs, scale down and store | 686 // average the two allpass outputs, scale down and store |
| 677 out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15; | 687 out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15; |
| 678 } | 688 } |
| 679 } | 689 } |
| OLD | NEW |