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
WebRtcSpl_Resample48khzTo32khz(const WebRtc_Word32 * In,WebRtc_Word32 * Out,const WebRtc_Word32 K)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
WebRtcSpl_Resample32khzTo24khz(const WebRtc_Word32 * In,WebRtc_Word32 * Out,const WebRtc_Word32 K)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
WebRtcSpl_ResampDotProduct(const WebRtc_Word32 * in1,const WebRtc_Word32 * in2,const WebRtc_Word16 * coef_ptr,WebRtc_Word32 * out1,WebRtc_Word32 * out2)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
WebRtcSpl_Resample44khzTo32khz(const WebRtc_Word32 * In,WebRtc_Word32 * Out,const WebRtc_Word32 K)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