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