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