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 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 
WebRtcSpl_Resample48khzTo32khz(const int32_t * In,int32_t * Out,int32_t K)44 void WebRtcSpl_Resample48khzTo32khz(const int32_t *In, int32_t *Out,
45                                     int32_t 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     int32_t tmp;
53     int32_t 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:  int32_t (normalized, not saturated) :: size 4 * K
87 // output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 3 * K
88 //      K: number of blocks
89 
WebRtcSpl_Resample32khzTo24khz(const int32_t * In,int32_t * Out,int32_t K)90 void WebRtcSpl_Resample32khzTo24khz(const int32_t *In, int32_t *Out,
91                                     int32_t 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     int32_t m;
99     int32_t 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 int32_t * in1,const int32_t * in2,const int16_t * coef_ptr,int32_t * out1,int32_t * out2)149 static void WebRtcSpl_ResampDotProduct(const int32_t *in1, const int32_t *in2,
150                                        const int16_t *coef_ptr, int32_t *out1,
151                                        int32_t *out2)
152 {
153     int32_t tmp1 = 16384;
154     int32_t tmp2 = 16384;
155     int16_t 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:  int32_t (normalized, not saturated) :: size 11 * K
196 // output: int32_t (shifted 15 positions to the left, + offset 16384) :: size  8 * K
197 //      K: number of blocks
198 
WebRtcSpl_Resample44khzTo32khz(const int32_t * In,int32_t * Out,int32_t K)199 void WebRtcSpl_Resample44khzTo32khz(const int32_t *In, int32_t *Out,
200                                     int32_t 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     int32_t tmp;
208     int32_t m;
209 
210     for (m = 0; m < K; m++)
211     {
212         tmp = 1 << 14;
213 
214         // first output sample
215         Out[0] = ((int32_t)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