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 functions between 48, 44, 32 and 24 kHz. 14 * The description headers can be found in signal_processing_library.h 15 * 16 */ 17 18 #include "signal_processing_library.h" 19 20 // interpolation coefficients 21 static const WebRtc_Word16 kCoefficients48To32[2][8] = { 22 {778, -2050, 1087, 23285, 12903, -3783, 441, 222}, 23 {222, 441, -3783, 12903, 23285, 1087, -2050, 778} 24 }; 25 26 static const WebRtc_Word16 kCoefficients32To24[3][8] = { 27 {767, -2362, 2434, 24406, 10620, -3838, 721, 90}, 28 {386, -381, -2646, 19062, 19062, -2646, -381, 386}, 29 {90, 721, -3838, 10620, 24406, 2434, -2362, 767} 30 }; 31 32 static const WebRtc_Word16 kCoefficients44To32[4][9] = { 33 {117, -669, 2245, -6183, 26267, 13529, -3245, 845, -138}, 34 {-101, 612, -2283, 8532, 29790, -5138, 1789, -524, 91}, 35 {50, -292, 1016, -3064, 32010, 3933, -1147, 315, -53}, 36 {-156, 974, -3863, 18603, 21691, -6246, 2353, -712, 126} 37 }; 38 39 // Resampling ratio: 2/3 40 // input: WebRtc_Word32 (normalized, not saturated) :: size 3 * K 41 // output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 2 * K 42 // K: number of blocks 43 44 void WebRtcSpl_Resample48khzTo32khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out, 45 const WebRtc_Word32 K) 46 { 47 ///////////////////////////////////////////////////////////// 48 // Filter operation: 49 // 50 // Perform resampling (3 input samples -> 2 output samples); 51 // process in sub blocks of size 3 samples. 52 WebRtc_Word32 tmp; 53 WebRtc_Word32 m; 54 55 for (m = 0; m < K; m++) 56 { 57 tmp = 1 << 14; 58 tmp += kCoefficients48To32[0][0] * In[0]; 59 tmp += kCoefficients48To32[0][1] * In[1]; 60 tmp += kCoefficients48To32[0][2] * In[2]; 61 tmp += kCoefficients48To32[0][3] * In[3]; 62 tmp += kCoefficients48To32[0][4] * In[4]; 63 tmp += kCoefficients48To32[0][5] * In[5]; 64 tmp += kCoefficients48To32[0][6] * In[6]; 65 tmp += kCoefficients48To32[0][7] * In[7]; 66 Out[0] = tmp; 67 68 tmp = 1 << 14; 69 tmp += kCoefficients48To32[1][0] * In[1]; 70 tmp += kCoefficients48To32[1][1] * In[2]; 71 tmp += kCoefficients48To32[1][2] * In[3]; 72 tmp += kCoefficients48To32[1][3] * In[4]; 73 tmp += kCoefficients48To32[1][4] * In[5]; 74 tmp += kCoefficients48To32[1][5] * In[6]; 75 tmp += kCoefficients48To32[1][6] * In[7]; 76 tmp += kCoefficients48To32[1][7] * In[8]; 77 Out[1] = tmp; 78 79 // update pointers 80 In += 3; 81 Out += 2; 82 } 83 } 84 85 // Resampling ratio: 3/4 86 // input: WebRtc_Word32 (normalized, not saturated) :: size 4 * K 87 // output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 3 * K 88 // K: number of blocks 89 90 void WebRtcSpl_Resample32khzTo24khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out, 91 const WebRtc_Word32 K) 92 { 93 ///////////////////////////////////////////////////////////// 94 // Filter operation: 95 // 96 // Perform resampling (4 input samples -> 3 output samples); 97 // process in sub blocks of size 4 samples. 98 WebRtc_Word32 m; 99 WebRtc_Word32 tmp; 100 101 for (m = 0; m < K; m++) 102 { 103 tmp = 1 << 14; 104 tmp += kCoefficients32To24[0][0] * In[0]; 105 tmp += kCoefficients32To24[0][1] * In[1]; 106 tmp += kCoefficients32To24[0][2] * In[2]; 107 tmp += kCoefficients32To24[0][3] * In[3]; 108 tmp += kCoefficients32To24[0][4] * In[4]; 109 tmp += kCoefficients32To24[0][5] * In[5]; 110 tmp += kCoefficients32To24[0][6] * In[6]; 111 tmp += kCoefficients32To24[0][7] * In[7]; 112 Out[0] = tmp; 113 114 tmp = 1 << 14; 115 tmp += kCoefficients32To24[1][0] * In[1]; 116 tmp += kCoefficients32To24[1][1] * In[2]; 117 tmp += kCoefficients32To24[1][2] * In[3]; 118 tmp += kCoefficients32To24[1][3] * In[4]; 119 tmp += kCoefficients32To24[1][4] * In[5]; 120 tmp += kCoefficients32To24[1][5] * In[6]; 121 tmp += kCoefficients32To24[1][6] * In[7]; 122 tmp += kCoefficients32To24[1][7] * In[8]; 123 Out[1] = tmp; 124 125 tmp = 1 << 14; 126 tmp += kCoefficients32To24[2][0] * In[2]; 127 tmp += kCoefficients32To24[2][1] * In[3]; 128 tmp += kCoefficients32To24[2][2] * In[4]; 129 tmp += kCoefficients32To24[2][3] * In[5]; 130 tmp += kCoefficients32To24[2][4] * In[6]; 131 tmp += kCoefficients32To24[2][5] * In[7]; 132 tmp += kCoefficients32To24[2][6] * In[8]; 133 tmp += kCoefficients32To24[2][7] * In[9]; 134 Out[2] = tmp; 135 136 // update pointers 137 In += 4; 138 Out += 3; 139 } 140 } 141 142 // 143 // fractional resampling filters 144 // Fout = 11/16 * Fin 145 // Fout = 8/11 * Fin 146 // 147 148 // compute two inner-products and store them to output array 149 static void WebRtcSpl_ResampDotProduct(const WebRtc_Word32 *in1, const WebRtc_Word32 *in2, 150 const WebRtc_Word16 *coef_ptr, WebRtc_Word32 *out1, 151 WebRtc_Word32 *out2) 152 { 153 WebRtc_Word32 tmp1 = 16384; 154 WebRtc_Word32 tmp2 = 16384; 155 WebRtc_Word16 coef; 156 157 coef = coef_ptr[0]; 158 tmp1 += coef * in1[0]; 159 tmp2 += coef * in2[-0]; 160 161 coef = coef_ptr[1]; 162 tmp1 += coef * in1[1]; 163 tmp2 += coef * in2[-1]; 164 165 coef = coef_ptr[2]; 166 tmp1 += coef * in1[2]; 167 tmp2 += coef * in2[-2]; 168 169 coef = coef_ptr[3]; 170 tmp1 += coef * in1[3]; 171 tmp2 += coef * in2[-3]; 172 173 coef = coef_ptr[4]; 174 tmp1 += coef * in1[4]; 175 tmp2 += coef * in2[-4]; 176 177 coef = coef_ptr[5]; 178 tmp1 += coef * in1[5]; 179 tmp2 += coef * in2[-5]; 180 181 coef = coef_ptr[6]; 182 tmp1 += coef * in1[6]; 183 tmp2 += coef * in2[-6]; 184 185 coef = coef_ptr[7]; 186 tmp1 += coef * in1[7]; 187 tmp2 += coef * in2[-7]; 188 189 coef = coef_ptr[8]; 190 *out1 = tmp1 + coef * in1[8]; 191 *out2 = tmp2 + coef * in2[-8]; 192 } 193 194 // Resampling ratio: 8/11 195 // input: WebRtc_Word32 (normalized, not saturated) :: size 11 * K 196 // output: WebRtc_Word32 (shifted 15 positions to the left, + offset 16384) :: size 8 * K 197 // K: number of blocks 198 199 void WebRtcSpl_Resample44khzTo32khz(const WebRtc_Word32 *In, WebRtc_Word32 *Out, 200 const WebRtc_Word32 K) 201 { 202 ///////////////////////////////////////////////////////////// 203 // Filter operation: 204 // 205 // Perform resampling (11 input samples -> 8 output samples); 206 // process in sub blocks of size 11 samples. 207 WebRtc_Word32 tmp; 208 WebRtc_Word32 m; 209 210 for (m = 0; m < K; m++) 211 { 212 tmp = 1 << 14; 213 214 // first output sample 215 Out[0] = ((WebRtc_Word32)In[3] << 15) + tmp; 216 217 // sum and accumulate filter coefficients and input samples 218 tmp += kCoefficients44To32[3][0] * In[5]; 219 tmp += kCoefficients44To32[3][1] * In[6]; 220 tmp += kCoefficients44To32[3][2] * In[7]; 221 tmp += kCoefficients44To32[3][3] * In[8]; 222 tmp += kCoefficients44To32[3][4] * In[9]; 223 tmp += kCoefficients44To32[3][5] * In[10]; 224 tmp += kCoefficients44To32[3][6] * In[11]; 225 tmp += kCoefficients44To32[3][7] * In[12]; 226 tmp += kCoefficients44To32[3][8] * In[13]; 227 Out[4] = tmp; 228 229 // sum and accumulate filter coefficients and input samples 230 WebRtcSpl_ResampDotProduct(&In[0], &In[17], kCoefficients44To32[0], &Out[1], &Out[7]); 231 232 // sum and accumulate filter coefficients and input samples 233 WebRtcSpl_ResampDotProduct(&In[2], &In[15], kCoefficients44To32[1], &Out[2], &Out[6]); 234 235 // sum and accumulate filter coefficients and input samples 236 WebRtcSpl_ResampDotProduct(&In[3], &In[14], kCoefficients44To32[2], &Out[3], &Out[5]); 237 238 // update pointers 239 In += 11; 240 Out += 8; 241 } 242 } 243