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 file contains the resampling by two functions. 14 * The description header can be found in signal_processing_library.h 15 * 16 */ 17 18 #include "signal_processing_library.h" 19 20 // allpass filter coefficients. 21 static const WebRtc_UWord16 kResampleAllpass1[3] = {3284, 24441, 49528}; 22 static const WebRtc_UWord16 kResampleAllpass2[3] = {12199, 37471, 60255}; 23 24 // decimator 25 void WebRtcSpl_DownsampleBy2(const WebRtc_Word16* in, const WebRtc_Word16 len, 26 WebRtc_Word16* out, WebRtc_Word32* filtState) 27 { 28 const WebRtc_Word16 *inptr; 29 WebRtc_Word16 *outptr; 30 WebRtc_Word32 *state; 31 WebRtc_Word32 tmp1, tmp2, diff, in32, out32; 32 WebRtc_Word16 i; 33 34 // local versions of pointers to input and output arrays 35 inptr = in; // input array 36 outptr = out; // output array (of length len/2) 37 state = filtState; // filter state array; length = 8 38 39 for (i = (len >> 1); i > 0; i--) 40 { 41 // lower allpass filter 42 in32 = (WebRtc_Word32)(*inptr++) << 10; 43 diff = in32 - state[1]; 44 tmp1 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[0], diff, state[0] ); 45 state[0] = in32; 46 diff = tmp1 - state[2]; 47 tmp2 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[1], diff, state[1] ); 48 state[1] = tmp1; 49 diff = tmp2 - state[3]; 50 state[3] = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[2], diff, state[2] ); 51 state[2] = tmp2; 52 53 // upper allpass filter 54 in32 = (WebRtc_Word32)(*inptr++) << 10; 55 diff = in32 - state[5]; 56 tmp1 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[0], diff, state[4] ); 57 state[4] = in32; 58 diff = tmp1 - state[6]; 59 tmp2 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[1], diff, state[5] ); 60 state[5] = tmp1; 61 diff = tmp2 - state[7]; 62 state[7] = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[2], diff, state[6] ); 63 state[6] = tmp2; 64 65 // add two allpass outputs, divide by two and round 66 out32 = (state[3] + state[7] + 1024) >> 11; 67 68 // limit amplitude to prevent wrap-around, and write to output array 69 if (out32 > 32767) 70 *outptr++ = 32767; 71 else if (out32 < -32768) 72 *outptr++ = -32768; 73 else 74 *outptr++ = (WebRtc_Word16)out32; 75 } 76 } 77 78 void WebRtcSpl_UpsampleBy2(const WebRtc_Word16* in, WebRtc_Word16 len, WebRtc_Word16* out, 79 WebRtc_Word32* filtState) 80 { 81 const WebRtc_Word16 *inptr; 82 WebRtc_Word16 *outptr; 83 WebRtc_Word32 *state; 84 WebRtc_Word32 tmp1, tmp2, diff, in32, out32; 85 WebRtc_Word16 i; 86 87 // local versions of pointers to input and output arrays 88 inptr = in; // input array 89 outptr = out; // output array (of length len*2) 90 state = filtState; // filter state array; length = 8 91 92 for (i = len; i > 0; i--) 93 { 94 // lower allpass filter 95 in32 = (WebRtc_Word32)(*inptr++) << 10; 96 diff = in32 - state[1]; 97 tmp1 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[0], diff, state[0] ); 98 state[0] = in32; 99 diff = tmp1 - state[2]; 100 tmp2 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[1], diff, state[1] ); 101 state[1] = tmp1; 102 diff = tmp2 - state[3]; 103 state[3] = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass1[2], diff, state[2] ); 104 state[2] = tmp2; 105 106 // round; limit amplitude to prevent wrap-around; write to output array 107 out32 = (state[3] + 512) >> 10; 108 if (out32 > 32767) 109 *outptr++ = 32767; 110 else if (out32 < -32768) 111 *outptr++ = -32768; 112 else 113 *outptr++ = (WebRtc_Word16)out32; 114 115 // upper allpass filter 116 diff = in32 - state[5]; 117 tmp1 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[0], diff, state[4] ); 118 state[4] = in32; 119 diff = tmp1 - state[6]; 120 tmp2 = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[1], diff, state[5] ); 121 state[5] = tmp1; 122 diff = tmp2 - state[7]; 123 state[7] = WEBRTC_SPL_SCALEDIFF32( kResampleAllpass2[2], diff, state[6] ); 124 state[6] = tmp2; 125 126 // round; limit amplitude to prevent wrap-around; write to output array 127 out32 = (state[7] + 512) >> 10; 128 if (out32 > 32767) 129 *outptr++ = 32767; 130 else if (out32 < -32768) 131 *outptr++ = -32768; 132 else 133 *outptr++ = (WebRtc_Word16)out32; 134 } 135 } 136