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
21static 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
26static 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
32static 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
44void 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
90void 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
149static 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
199void 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