|  | /* | 
|  | *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | 
|  | * | 
|  | *  Use of this source code is governed by a BSD-style license | 
|  | *  that can be found in the LICENSE file in the root of the source | 
|  | *  tree. An additional intellectual property rights grant can be found | 
|  | *  in the file PATENTS.  All contributing project authors may | 
|  | *  be found in the AUTHORS file in the root of the source tree. | 
|  | */ | 
|  |  | 
|  |  | 
|  | /* | 
|  | * This header file contains some internal resampling functions. | 
|  | * | 
|  | */ | 
|  |  | 
|  | #include "common_audio/signal_processing/resample_by_2_internal.h" | 
|  | #include "rtc_base/sanitizer.h" | 
|  |  | 
|  | // allpass filter coefficients. | 
|  | static const int16_t kResampleAllpass[2][3] = { | 
|  | {821, 6110, 12382}, | 
|  | {3050, 9368, 15063} | 
|  | }; | 
|  |  | 
|  | // | 
|  | //   decimator | 
|  | // input:  int32_t (shifted 15 positions to the left, + offset 16384) OVERWRITTEN! | 
|  | // output: int16_t (saturated) (of length len/2) | 
|  | // state:  filter state array; length = 8 | 
|  |  | 
|  | 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) | 
|  | { | 
|  | int32_t tmp0, tmp1, diff; | 
|  | int32_t i; | 
|  |  | 
|  | len >>= 1; | 
|  |  | 
|  | // lower allpass filter (operates on even input samples) | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | tmp0 = in[i << 1]; | 
|  | diff = tmp0 - state[1]; | 
|  | // UBSan: -1771017321 - 999586185 cannot be represented in type 'int' | 
|  |  | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[0] + diff * kResampleAllpass[1][0]; | 
|  | state[0] = tmp0; | 
|  | diff = tmp1 - state[2]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[1] + diff * kResampleAllpass[1][1]; | 
|  | state[1] = tmp1; | 
|  | diff = tmp0 - state[3]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[3] = state[2] + diff * kResampleAllpass[1][2]; | 
|  | state[2] = tmp0; | 
|  |  | 
|  | // divide by two and store temporarily | 
|  | in[i << 1] = (state[3] >> 1); | 
|  | } | 
|  |  | 
|  | in++; | 
|  |  | 
|  | // upper allpass filter (operates on odd input samples) | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | tmp0 = in[i << 1]; | 
|  | diff = tmp0 - state[5]; | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[4] + diff * kResampleAllpass[0][0]; | 
|  | state[4] = tmp0; | 
|  | diff = tmp1 - state[6]; | 
|  | // scale down and round | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[5] + diff * kResampleAllpass[0][1]; | 
|  | state[5] = tmp1; | 
|  | diff = tmp0 - state[7]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[7] = state[6] + diff * kResampleAllpass[0][2]; | 
|  | state[6] = tmp0; | 
|  |  | 
|  | // divide by two and store temporarily | 
|  | in[i << 1] = (state[7] >> 1); | 
|  | } | 
|  |  | 
|  | in--; | 
|  |  | 
|  | // combine allpass outputs | 
|  | for (i = 0; i < len; i += 2) | 
|  | { | 
|  | // divide by two, add both allpass outputs and round | 
|  | tmp0 = (in[i << 1] + in[(i << 1) + 1]) >> 15; | 
|  | tmp1 = (in[(i << 1) + 2] + in[(i << 1) + 3]) >> 15; | 
|  | if (tmp0 > (int32_t)0x00007FFF) | 
|  | tmp0 = 0x00007FFF; | 
|  | if (tmp0 < (int32_t)0xFFFF8000) | 
|  | tmp0 = 0xFFFF8000; | 
|  | out[i] = (int16_t)tmp0; | 
|  | if (tmp1 > (int32_t)0x00007FFF) | 
|  | tmp1 = 0x00007FFF; | 
|  | if (tmp1 < (int32_t)0xFFFF8000) | 
|  | tmp1 = 0xFFFF8000; | 
|  | out[i + 1] = (int16_t)tmp1; | 
|  | } | 
|  | } | 
|  |  | 
|  | // | 
|  | //   decimator | 
|  | // input:  int16_t | 
|  | // output: int32_t (shifted 15 positions to the left, + offset 16384) (of length len/2) | 
|  | // state:  filter state array; length = 8 | 
|  |  | 
|  | 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) | 
|  | { | 
|  | int32_t tmp0, tmp1, diff; | 
|  | int32_t i; | 
|  |  | 
|  | len >>= 1; | 
|  |  | 
|  | // lower allpass filter (operates on even input samples) | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); | 
|  | diff = tmp0 - state[1]; | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[0] + diff * kResampleAllpass[1][0]; | 
|  | state[0] = tmp0; | 
|  | diff = tmp1 - state[2]; | 
|  | // UBSan: -1379909682 - 834099714 cannot be represented in type 'int' | 
|  |  | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[1] + diff * kResampleAllpass[1][1]; | 
|  | state[1] = tmp1; | 
|  | diff = tmp0 - state[3]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[3] = state[2] + diff * kResampleAllpass[1][2]; | 
|  | state[2] = tmp0; | 
|  |  | 
|  | // divide by two and store temporarily | 
|  | out[i] = (state[3] >> 1); | 
|  | } | 
|  |  | 
|  | in++; | 
|  |  | 
|  | // upper allpass filter (operates on odd input samples) | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); | 
|  | diff = tmp0 - state[5]; | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[4] + diff * kResampleAllpass[0][0]; | 
|  | state[4] = tmp0; | 
|  | diff = tmp1 - state[6]; | 
|  | // scale down and round | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[5] + diff * kResampleAllpass[0][1]; | 
|  | state[5] = tmp1; | 
|  | diff = tmp0 - state[7]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[7] = state[6] + diff * kResampleAllpass[0][2]; | 
|  | state[6] = tmp0; | 
|  |  | 
|  | // divide by two and store temporarily | 
|  | out[i] += (state[7] >> 1); | 
|  | } | 
|  |  | 
|  | in--; | 
|  | } | 
|  |  | 
|  | // | 
|  | //   interpolator | 
|  | // input:  int16_t | 
|  | // output: int32_t (normalized, not saturated) (of length len*2) | 
|  | // state:  filter state array; length = 8 | 
|  | void WebRtcSpl_UpBy2ShortToInt(const int16_t *in, int32_t len, int32_t *out, | 
|  | int32_t *state) | 
|  | { | 
|  | int32_t tmp0, tmp1, diff; | 
|  | int32_t i; | 
|  |  | 
|  | // upper allpass filter (generates odd output samples) | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | tmp0 = ((int32_t)in[i] << 15) + (1 << 14); | 
|  | diff = tmp0 - state[5]; | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[4] + diff * kResampleAllpass[0][0]; | 
|  | state[4] = tmp0; | 
|  | diff = tmp1 - state[6]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[5] + diff * kResampleAllpass[0][1]; | 
|  | state[5] = tmp1; | 
|  | diff = tmp0 - state[7]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[7] = state[6] + diff * kResampleAllpass[0][2]; | 
|  | state[6] = tmp0; | 
|  |  | 
|  | // scale down, round and store | 
|  | out[i << 1] = state[7] >> 15; | 
|  | } | 
|  |  | 
|  | out++; | 
|  |  | 
|  | // lower allpass filter (generates even output samples) | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | tmp0 = ((int32_t)in[i] << 15) + (1 << 14); | 
|  | diff = tmp0 - state[1]; | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[0] + diff * kResampleAllpass[1][0]; | 
|  | state[0] = tmp0; | 
|  | diff = tmp1 - state[2]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[1] + diff * kResampleAllpass[1][1]; | 
|  | state[1] = tmp1; | 
|  | diff = tmp0 - state[3]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[3] = state[2] + diff * kResampleAllpass[1][2]; | 
|  | state[2] = tmp0; | 
|  |  | 
|  | // scale down, round and store | 
|  | out[i << 1] = state[3] >> 15; | 
|  | } | 
|  | } | 
|  |  | 
|  | // | 
|  | //   interpolator | 
|  | // input:  int32_t (shifted 15 positions to the left, + offset 16384) | 
|  | // output: int32_t (shifted 15 positions to the left, + offset 16384) (of length len*2) | 
|  | // state:  filter state array; length = 8 | 
|  | void WebRtcSpl_UpBy2IntToInt(const int32_t *in, int32_t len, int32_t *out, | 
|  | int32_t *state) | 
|  | { | 
|  | int32_t tmp0, tmp1, diff; | 
|  | int32_t i; | 
|  |  | 
|  | // upper allpass filter (generates odd output samples) | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | tmp0 = in[i]; | 
|  | diff = tmp0 - state[5]; | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[4] + diff * kResampleAllpass[0][0]; | 
|  | state[4] = tmp0; | 
|  | diff = tmp1 - state[6]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[5] + diff * kResampleAllpass[0][1]; | 
|  | state[5] = tmp1; | 
|  | diff = tmp0 - state[7]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[7] = state[6] + diff * kResampleAllpass[0][2]; | 
|  | state[6] = tmp0; | 
|  |  | 
|  | // scale down, round and store | 
|  | out[i << 1] = state[7]; | 
|  | } | 
|  |  | 
|  | out++; | 
|  |  | 
|  | // lower allpass filter (generates even output samples) | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | tmp0 = in[i]; | 
|  | diff = tmp0 - state[1]; | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[0] + diff * kResampleAllpass[1][0]; | 
|  | state[0] = tmp0; | 
|  | diff = tmp1 - state[2]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[1] + diff * kResampleAllpass[1][1]; | 
|  | state[1] = tmp1; | 
|  | diff = tmp0 - state[3]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[3] = state[2] + diff * kResampleAllpass[1][2]; | 
|  | state[2] = tmp0; | 
|  |  | 
|  | // scale down, round and store | 
|  | out[i << 1] = state[3]; | 
|  | } | 
|  | } | 
|  |  | 
|  | // | 
|  | //   interpolator | 
|  | // input:  int32_t (shifted 15 positions to the left, + offset 16384) | 
|  | // output: int16_t (saturated) (of length len*2) | 
|  | // state:  filter state array; length = 8 | 
|  | void WebRtcSpl_UpBy2IntToShort(const int32_t *in, int32_t len, int16_t *out, | 
|  | int32_t *state) | 
|  | { | 
|  | int32_t tmp0, tmp1, diff; | 
|  | int32_t i; | 
|  |  | 
|  | // upper allpass filter (generates odd output samples) | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | tmp0 = in[i]; | 
|  | diff = tmp0 - state[5]; | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[4] + diff * kResampleAllpass[0][0]; | 
|  | state[4] = tmp0; | 
|  | diff = tmp1 - state[6]; | 
|  | // scale down and round | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[5] + diff * kResampleAllpass[0][1]; | 
|  | state[5] = tmp1; | 
|  | diff = tmp0 - state[7]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[7] = state[6] + diff * kResampleAllpass[0][2]; | 
|  | state[6] = tmp0; | 
|  |  | 
|  | // scale down, saturate and store | 
|  | tmp1 = state[7] >> 15; | 
|  | if (tmp1 > (int32_t)0x00007FFF) | 
|  | tmp1 = 0x00007FFF; | 
|  | if (tmp1 < (int32_t)0xFFFF8000) | 
|  | tmp1 = 0xFFFF8000; | 
|  | out[i << 1] = (int16_t)tmp1; | 
|  | } | 
|  |  | 
|  | out++; | 
|  |  | 
|  | // lower allpass filter (generates even output samples) | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | tmp0 = in[i]; | 
|  | diff = tmp0 - state[1]; | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[0] + diff * kResampleAllpass[1][0]; | 
|  | state[0] = tmp0; | 
|  | diff = tmp1 - state[2]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[1] + diff * kResampleAllpass[1][1]; | 
|  | state[1] = tmp1; | 
|  | diff = tmp0 - state[3]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[3] = state[2] + diff * kResampleAllpass[1][2]; | 
|  | state[2] = tmp0; | 
|  |  | 
|  | // scale down, saturate and store | 
|  | tmp1 = state[3] >> 15; | 
|  | if (tmp1 > (int32_t)0x00007FFF) | 
|  | tmp1 = 0x00007FFF; | 
|  | if (tmp1 < (int32_t)0xFFFF8000) | 
|  | tmp1 = 0xFFFF8000; | 
|  | out[i << 1] = (int16_t)tmp1; | 
|  | } | 
|  | } | 
|  |  | 
|  | //   lowpass filter | 
|  | // input:  int16_t | 
|  | // output: int32_t (normalized, not saturated) | 
|  | // state:  filter state array; length = 8 | 
|  | void WebRtcSpl_LPBy2ShortToInt(const int16_t* in, int32_t len, int32_t* out, | 
|  | int32_t* state) | 
|  | { | 
|  | int32_t tmp0, tmp1, diff; | 
|  | int32_t i; | 
|  |  | 
|  | len >>= 1; | 
|  |  | 
|  | // lower allpass filter: odd input -> even output samples | 
|  | in++; | 
|  | // initial state of polyphase delay element | 
|  | tmp0 = state[12]; | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | diff = tmp0 - state[1]; | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[0] + diff * kResampleAllpass[1][0]; | 
|  | state[0] = tmp0; | 
|  | diff = tmp1 - state[2]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[1] + diff * kResampleAllpass[1][1]; | 
|  | state[1] = tmp1; | 
|  | diff = tmp0 - state[3]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[3] = state[2] + diff * kResampleAllpass[1][2]; | 
|  | state[2] = tmp0; | 
|  |  | 
|  | // scale down, round and store | 
|  | out[i << 1] = state[3] >> 1; | 
|  | tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); | 
|  | } | 
|  | in--; | 
|  |  | 
|  | // upper allpass filter: even input -> even output samples | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); | 
|  | diff = tmp0 - state[5]; | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[4] + diff * kResampleAllpass[0][0]; | 
|  | state[4] = tmp0; | 
|  | diff = tmp1 - state[6]; | 
|  | // scale down and round | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[5] + diff * kResampleAllpass[0][1]; | 
|  | state[5] = tmp1; | 
|  | diff = tmp0 - state[7]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[7] = state[6] + diff * kResampleAllpass[0][2]; | 
|  | state[6] = tmp0; | 
|  |  | 
|  | // average the two allpass outputs, scale down and store | 
|  | out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15; | 
|  | } | 
|  |  | 
|  | // switch to odd output samples | 
|  | out++; | 
|  |  | 
|  | // lower allpass filter: even input -> odd output samples | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); | 
|  | diff = tmp0 - state[9]; | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[8] + diff * kResampleAllpass[1][0]; | 
|  | state[8] = tmp0; | 
|  | diff = tmp1 - state[10]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[9] + diff * kResampleAllpass[1][1]; | 
|  | state[9] = tmp1; | 
|  | diff = tmp0 - state[11]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[11] = state[10] + diff * kResampleAllpass[1][2]; | 
|  | state[10] = tmp0; | 
|  |  | 
|  | // scale down, round and store | 
|  | out[i << 1] = state[11] >> 1; | 
|  | } | 
|  |  | 
|  | // upper allpass filter: odd input -> odd output samples | 
|  | in++; | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); | 
|  | diff = tmp0 - state[13]; | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[12] + diff * kResampleAllpass[0][0]; | 
|  | state[12] = tmp0; | 
|  | diff = tmp1 - state[14]; | 
|  | // scale down and round | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[13] + diff * kResampleAllpass[0][1]; | 
|  | state[13] = tmp1; | 
|  | diff = tmp0 - state[15]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[15] = state[14] + diff * kResampleAllpass[0][2]; | 
|  | state[14] = tmp0; | 
|  |  | 
|  | // average the two allpass outputs, scale down and store | 
|  | out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15; | 
|  | } | 
|  | } | 
|  |  | 
|  | //   lowpass filter | 
|  | // input:  int32_t (shifted 15 positions to the left, + offset 16384) | 
|  | // output: int32_t (normalized, not saturated) | 
|  | // state:  filter state array; length = 8 | 
|  | 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) | 
|  | { | 
|  | int32_t tmp0, tmp1, diff; | 
|  | int32_t i; | 
|  |  | 
|  | len >>= 1; | 
|  |  | 
|  | // lower allpass filter: odd input -> even output samples | 
|  | in++; | 
|  | // initial state of polyphase delay element | 
|  | tmp0 = state[12]; | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | diff = tmp0 - state[1]; | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[0] + diff * kResampleAllpass[1][0]; | 
|  | state[0] = tmp0; | 
|  | diff = tmp1 - state[2]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[1] + diff * kResampleAllpass[1][1]; | 
|  | state[1] = tmp1; | 
|  | diff = tmp0 - state[3]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[3] = state[2] + diff * kResampleAllpass[1][2]; | 
|  | state[2] = tmp0; | 
|  |  | 
|  | // scale down, round and store | 
|  | out[i << 1] = state[3] >> 1; | 
|  | tmp0 = in[i << 1]; | 
|  | } | 
|  | in--; | 
|  |  | 
|  | // upper allpass filter: even input -> even output samples | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | tmp0 = in[i << 1]; | 
|  | diff = tmp0 - state[5]; | 
|  | // UBSan: -794814117 - 1566149201 cannot be represented in type 'int' | 
|  |  | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[4] + diff * kResampleAllpass[0][0]; | 
|  | state[4] = tmp0; | 
|  | diff = tmp1 - state[6]; | 
|  | // scale down and round | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[5] + diff * kResampleAllpass[0][1]; | 
|  | state[5] = tmp1; | 
|  | diff = tmp0 - state[7]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[7] = state[6] + diff * kResampleAllpass[0][2]; | 
|  | state[6] = tmp0; | 
|  |  | 
|  | // average the two allpass outputs, scale down and store | 
|  | out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15; | 
|  | } | 
|  |  | 
|  | // switch to odd output samples | 
|  | out++; | 
|  |  | 
|  | // lower allpass filter: even input -> odd output samples | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | tmp0 = in[i << 1]; | 
|  | diff = tmp0 - state[9]; | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[8] + diff * kResampleAllpass[1][0]; | 
|  | state[8] = tmp0; | 
|  | diff = tmp1 - state[10]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[9] + diff * kResampleAllpass[1][1]; | 
|  | state[9] = tmp1; | 
|  | diff = tmp0 - state[11]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[11] = state[10] + diff * kResampleAllpass[1][2]; | 
|  | state[10] = tmp0; | 
|  |  | 
|  | // scale down, round and store | 
|  | out[i << 1] = state[11] >> 1; | 
|  | } | 
|  |  | 
|  | // upper allpass filter: odd input -> odd output samples | 
|  | in++; | 
|  | for (i = 0; i < len; i++) | 
|  | { | 
|  | tmp0 = in[i << 1]; | 
|  | diff = tmp0 - state[13]; | 
|  | // scale down and round | 
|  | diff = (diff + (1 << 13)) >> 14; | 
|  | tmp1 = state[12] + diff * kResampleAllpass[0][0]; | 
|  | state[12] = tmp0; | 
|  | diff = tmp1 - state[14]; | 
|  | // scale down and round | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | tmp0 = state[13] + diff * kResampleAllpass[0][1]; | 
|  | state[13] = tmp1; | 
|  | diff = tmp0 - state[15]; | 
|  | // scale down and truncate | 
|  | diff = diff >> 14; | 
|  | if (diff < 0) | 
|  | diff += 1; | 
|  | state[15] = state[14] + diff * kResampleAllpass[0][2]; | 
|  | state[14] = tmp0; | 
|  |  | 
|  | // average the two allpass outputs, scale down and store | 
|  | out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15; | 
|  | } | 
|  | } |