Line data Source code
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 "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
19 :
20 : // interpolation coefficients
21 : static const int16_t 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 int16_t 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 int16_t 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: int32_t (normalized, not saturated) :: size 3 * K
41 : // output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 2 * K
42 : // K: number of blocks
43 :
44 0 : void WebRtcSpl_Resample48khzTo32khz(const int32_t *In, int32_t *Out, size_t K)
45 : {
46 : /////////////////////////////////////////////////////////////
47 : // Filter operation:
48 : //
49 : // Perform resampling (3 input samples -> 2 output samples);
50 : // process in sub blocks of size 3 samples.
51 : int32_t tmp;
52 : size_t m;
53 :
54 0 : for (m = 0; m < K; m++)
55 : {
56 0 : tmp = 1 << 14;
57 0 : tmp += kCoefficients48To32[0][0] * In[0];
58 0 : tmp += kCoefficients48To32[0][1] * In[1];
59 0 : tmp += kCoefficients48To32[0][2] * In[2];
60 0 : tmp += kCoefficients48To32[0][3] * In[3];
61 0 : tmp += kCoefficients48To32[0][4] * In[4];
62 0 : tmp += kCoefficients48To32[0][5] * In[5];
63 0 : tmp += kCoefficients48To32[0][6] * In[6];
64 0 : tmp += kCoefficients48To32[0][7] * In[7];
65 0 : Out[0] = tmp;
66 :
67 0 : tmp = 1 << 14;
68 0 : tmp += kCoefficients48To32[1][0] * In[1];
69 0 : tmp += kCoefficients48To32[1][1] * In[2];
70 0 : tmp += kCoefficients48To32[1][2] * In[3];
71 0 : tmp += kCoefficients48To32[1][3] * In[4];
72 0 : tmp += kCoefficients48To32[1][4] * In[5];
73 0 : tmp += kCoefficients48To32[1][5] * In[6];
74 0 : tmp += kCoefficients48To32[1][6] * In[7];
75 0 : tmp += kCoefficients48To32[1][7] * In[8];
76 0 : Out[1] = tmp;
77 :
78 : // update pointers
79 0 : In += 3;
80 0 : Out += 2;
81 : }
82 0 : }
83 :
84 : // Resampling ratio: 3/4
85 : // input: int32_t (normalized, not saturated) :: size 4 * K
86 : // output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 3 * K
87 : // K: number of blocks
88 :
89 0 : void WebRtcSpl_Resample32khzTo24khz(const int32_t *In, int32_t *Out, size_t K)
90 : {
91 : /////////////////////////////////////////////////////////////
92 : // Filter operation:
93 : //
94 : // Perform resampling (4 input samples -> 3 output samples);
95 : // process in sub blocks of size 4 samples.
96 : size_t m;
97 : int32_t tmp;
98 :
99 0 : for (m = 0; m < K; m++)
100 : {
101 0 : tmp = 1 << 14;
102 0 : tmp += kCoefficients32To24[0][0] * In[0];
103 0 : tmp += kCoefficients32To24[0][1] * In[1];
104 0 : tmp += kCoefficients32To24[0][2] * In[2];
105 0 : tmp += kCoefficients32To24[0][3] * In[3];
106 0 : tmp += kCoefficients32To24[0][4] * In[4];
107 0 : tmp += kCoefficients32To24[0][5] * In[5];
108 0 : tmp += kCoefficients32To24[0][6] * In[6];
109 0 : tmp += kCoefficients32To24[0][7] * In[7];
110 0 : Out[0] = tmp;
111 :
112 0 : tmp = 1 << 14;
113 0 : tmp += kCoefficients32To24[1][0] * In[1];
114 0 : tmp += kCoefficients32To24[1][1] * In[2];
115 0 : tmp += kCoefficients32To24[1][2] * In[3];
116 0 : tmp += kCoefficients32To24[1][3] * In[4];
117 0 : tmp += kCoefficients32To24[1][4] * In[5];
118 0 : tmp += kCoefficients32To24[1][5] * In[6];
119 0 : tmp += kCoefficients32To24[1][6] * In[7];
120 0 : tmp += kCoefficients32To24[1][7] * In[8];
121 0 : Out[1] = tmp;
122 :
123 0 : tmp = 1 << 14;
124 0 : tmp += kCoefficients32To24[2][0] * In[2];
125 0 : tmp += kCoefficients32To24[2][1] * In[3];
126 0 : tmp += kCoefficients32To24[2][2] * In[4];
127 0 : tmp += kCoefficients32To24[2][3] * In[5];
128 0 : tmp += kCoefficients32To24[2][4] * In[6];
129 0 : tmp += kCoefficients32To24[2][5] * In[7];
130 0 : tmp += kCoefficients32To24[2][6] * In[8];
131 0 : tmp += kCoefficients32To24[2][7] * In[9];
132 0 : Out[2] = tmp;
133 :
134 : // update pointers
135 0 : In += 4;
136 0 : Out += 3;
137 : }
138 0 : }
139 :
140 : //
141 : // fractional resampling filters
142 : // Fout = 11/16 * Fin
143 : // Fout = 8/11 * Fin
144 : //
145 :
146 : // compute two inner-products and store them to output array
147 0 : static void WebRtcSpl_ResampDotProduct(const int32_t *in1, const int32_t *in2,
148 : const int16_t *coef_ptr, int32_t *out1,
149 : int32_t *out2)
150 : {
151 0 : int32_t tmp1 = 16384;
152 0 : int32_t tmp2 = 16384;
153 : int16_t coef;
154 :
155 0 : coef = coef_ptr[0];
156 0 : tmp1 += coef * in1[0];
157 0 : tmp2 += coef * in2[-0];
158 :
159 0 : coef = coef_ptr[1];
160 0 : tmp1 += coef * in1[1];
161 0 : tmp2 += coef * in2[-1];
162 :
163 0 : coef = coef_ptr[2];
164 0 : tmp1 += coef * in1[2];
165 0 : tmp2 += coef * in2[-2];
166 :
167 0 : coef = coef_ptr[3];
168 0 : tmp1 += coef * in1[3];
169 0 : tmp2 += coef * in2[-3];
170 :
171 0 : coef = coef_ptr[4];
172 0 : tmp1 += coef * in1[4];
173 0 : tmp2 += coef * in2[-4];
174 :
175 0 : coef = coef_ptr[5];
176 0 : tmp1 += coef * in1[5];
177 0 : tmp2 += coef * in2[-5];
178 :
179 0 : coef = coef_ptr[6];
180 0 : tmp1 += coef * in1[6];
181 0 : tmp2 += coef * in2[-6];
182 :
183 0 : coef = coef_ptr[7];
184 0 : tmp1 += coef * in1[7];
185 0 : tmp2 += coef * in2[-7];
186 :
187 0 : coef = coef_ptr[8];
188 0 : *out1 = tmp1 + coef * in1[8];
189 0 : *out2 = tmp2 + coef * in2[-8];
190 0 : }
191 :
192 : // Resampling ratio: 8/11
193 : // input: int32_t (normalized, not saturated) :: size 11 * K
194 : // output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 8 * K
195 : // K: number of blocks
196 :
197 0 : void WebRtcSpl_Resample44khzTo32khz(const int32_t *In, int32_t *Out, size_t K)
198 : {
199 : /////////////////////////////////////////////////////////////
200 : // Filter operation:
201 : //
202 : // Perform resampling (11 input samples -> 8 output samples);
203 : // process in sub blocks of size 11 samples.
204 : int32_t tmp;
205 : size_t m;
206 :
207 0 : for (m = 0; m < K; m++)
208 : {
209 0 : tmp = 1 << 14;
210 :
211 : // first output sample
212 0 : Out[0] = ((int32_t)In[3] << 15) + tmp;
213 :
214 : // sum and accumulate filter coefficients and input samples
215 0 : tmp += kCoefficients44To32[3][0] * In[5];
216 0 : tmp += kCoefficients44To32[3][1] * In[6];
217 0 : tmp += kCoefficients44To32[3][2] * In[7];
218 0 : tmp += kCoefficients44To32[3][3] * In[8];
219 0 : tmp += kCoefficients44To32[3][4] * In[9];
220 0 : tmp += kCoefficients44To32[3][5] * In[10];
221 0 : tmp += kCoefficients44To32[3][6] * In[11];
222 0 : tmp += kCoefficients44To32[3][7] * In[12];
223 0 : tmp += kCoefficients44To32[3][8] * In[13];
224 0 : Out[4] = tmp;
225 :
226 : // sum and accumulate filter coefficients and input samples
227 0 : WebRtcSpl_ResampDotProduct(&In[0], &In[17], kCoefficients44To32[0], &Out[1], &Out[7]);
228 :
229 : // sum and accumulate filter coefficients and input samples
230 0 : WebRtcSpl_ResampDotProduct(&In[2], &In[15], kCoefficients44To32[1], &Out[2], &Out[6]);
231 :
232 : // sum and accumulate filter coefficients and input samples
233 0 : WebRtcSpl_ResampDotProduct(&In[3], &In[14], kCoefficients44To32[2], &Out[3], &Out[5]);
234 :
235 : // update pointers
236 0 : In += 11;
237 0 : Out += 8;
238 : }
239 0 : }
|