xref: /aosp_15_r20/external/webrtc/common_audio/resampler/resampler.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker /*
12*d9f75844SAndroid Build Coastguard Worker  * A wrapper for resampling a numerous amount of sampling combinations.
13*d9f75844SAndroid Build Coastguard Worker  */
14*d9f75844SAndroid Build Coastguard Worker 
15*d9f75844SAndroid Build Coastguard Worker #include "common_audio/resampler/include/resampler.h"
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker #include <stdint.h>
18*d9f75844SAndroid Build Coastguard Worker #include <stdlib.h>
19*d9f75844SAndroid Build Coastguard Worker #include <string.h>
20*d9f75844SAndroid Build Coastguard Worker 
21*d9f75844SAndroid Build Coastguard Worker #include "common_audio/signal_processing/include/signal_processing_library.h"
22*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h"
23*d9f75844SAndroid Build Coastguard Worker 
24*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
25*d9f75844SAndroid Build Coastguard Worker 
Resampler()26*d9f75844SAndroid Build Coastguard Worker Resampler::Resampler()
27*d9f75844SAndroid Build Coastguard Worker     : state1_(nullptr),
28*d9f75844SAndroid Build Coastguard Worker       state2_(nullptr),
29*d9f75844SAndroid Build Coastguard Worker       state3_(nullptr),
30*d9f75844SAndroid Build Coastguard Worker       in_buffer_(nullptr),
31*d9f75844SAndroid Build Coastguard Worker       out_buffer_(nullptr),
32*d9f75844SAndroid Build Coastguard Worker       in_buffer_size_(0),
33*d9f75844SAndroid Build Coastguard Worker       out_buffer_size_(0),
34*d9f75844SAndroid Build Coastguard Worker       in_buffer_size_max_(0),
35*d9f75844SAndroid Build Coastguard Worker       out_buffer_size_max_(0),
36*d9f75844SAndroid Build Coastguard Worker       my_in_frequency_khz_(0),
37*d9f75844SAndroid Build Coastguard Worker       my_out_frequency_khz_(0),
38*d9f75844SAndroid Build Coastguard Worker       my_mode_(kResamplerMode1To1),
39*d9f75844SAndroid Build Coastguard Worker       num_channels_(0),
40*d9f75844SAndroid Build Coastguard Worker       helper_left_(nullptr),
41*d9f75844SAndroid Build Coastguard Worker       helper_right_(nullptr) {}
42*d9f75844SAndroid Build Coastguard Worker 
Resampler(int inFreq,int outFreq,size_t num_channels)43*d9f75844SAndroid Build Coastguard Worker Resampler::Resampler(int inFreq, int outFreq, size_t num_channels)
44*d9f75844SAndroid Build Coastguard Worker     : Resampler() {
45*d9f75844SAndroid Build Coastguard Worker   Reset(inFreq, outFreq, num_channels);
46*d9f75844SAndroid Build Coastguard Worker }
47*d9f75844SAndroid Build Coastguard Worker 
~Resampler()48*d9f75844SAndroid Build Coastguard Worker Resampler::~Resampler() {
49*d9f75844SAndroid Build Coastguard Worker   if (state1_) {
50*d9f75844SAndroid Build Coastguard Worker     free(state1_);
51*d9f75844SAndroid Build Coastguard Worker   }
52*d9f75844SAndroid Build Coastguard Worker   if (state2_) {
53*d9f75844SAndroid Build Coastguard Worker     free(state2_);
54*d9f75844SAndroid Build Coastguard Worker   }
55*d9f75844SAndroid Build Coastguard Worker   if (state3_) {
56*d9f75844SAndroid Build Coastguard Worker     free(state3_);
57*d9f75844SAndroid Build Coastguard Worker   }
58*d9f75844SAndroid Build Coastguard Worker   if (in_buffer_) {
59*d9f75844SAndroid Build Coastguard Worker     free(in_buffer_);
60*d9f75844SAndroid Build Coastguard Worker   }
61*d9f75844SAndroid Build Coastguard Worker   if (out_buffer_) {
62*d9f75844SAndroid Build Coastguard Worker     free(out_buffer_);
63*d9f75844SAndroid Build Coastguard Worker   }
64*d9f75844SAndroid Build Coastguard Worker   if (helper_left_) {
65*d9f75844SAndroid Build Coastguard Worker     delete helper_left_;
66*d9f75844SAndroid Build Coastguard Worker   }
67*d9f75844SAndroid Build Coastguard Worker   if (helper_right_) {
68*d9f75844SAndroid Build Coastguard Worker     delete helper_right_;
69*d9f75844SAndroid Build Coastguard Worker   }
70*d9f75844SAndroid Build Coastguard Worker }
71*d9f75844SAndroid Build Coastguard Worker 
ResetIfNeeded(int inFreq,int outFreq,size_t num_channels)72*d9f75844SAndroid Build Coastguard Worker int Resampler::ResetIfNeeded(int inFreq, int outFreq, size_t num_channels) {
73*d9f75844SAndroid Build Coastguard Worker   int tmpInFreq_kHz = inFreq / 1000;
74*d9f75844SAndroid Build Coastguard Worker   int tmpOutFreq_kHz = outFreq / 1000;
75*d9f75844SAndroid Build Coastguard Worker 
76*d9f75844SAndroid Build Coastguard Worker   if ((tmpInFreq_kHz != my_in_frequency_khz_) ||
77*d9f75844SAndroid Build Coastguard Worker       (tmpOutFreq_kHz != my_out_frequency_khz_) ||
78*d9f75844SAndroid Build Coastguard Worker       (num_channels != num_channels_)) {
79*d9f75844SAndroid Build Coastguard Worker     return Reset(inFreq, outFreq, num_channels);
80*d9f75844SAndroid Build Coastguard Worker   } else {
81*d9f75844SAndroid Build Coastguard Worker     return 0;
82*d9f75844SAndroid Build Coastguard Worker   }
83*d9f75844SAndroid Build Coastguard Worker }
84*d9f75844SAndroid Build Coastguard Worker 
Reset(int inFreq,int outFreq,size_t num_channels)85*d9f75844SAndroid Build Coastguard Worker int Resampler::Reset(int inFreq, int outFreq, size_t num_channels) {
86*d9f75844SAndroid Build Coastguard Worker   if (num_channels != 1 && num_channels != 2) {
87*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_WARNING)
88*d9f75844SAndroid Build Coastguard Worker         << "Reset() called with unsupported channel count, num_channels = "
89*d9f75844SAndroid Build Coastguard Worker         << num_channels;
90*d9f75844SAndroid Build Coastguard Worker     return -1;
91*d9f75844SAndroid Build Coastguard Worker   }
92*d9f75844SAndroid Build Coastguard Worker   ResamplerMode mode;
93*d9f75844SAndroid Build Coastguard Worker   if (ComputeResamplerMode(inFreq, outFreq, &mode) != 0) {
94*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_WARNING)
95*d9f75844SAndroid Build Coastguard Worker         << "Reset() called with unsupported sample rates, inFreq = " << inFreq
96*d9f75844SAndroid Build Coastguard Worker         << ", outFreq = " << outFreq;
97*d9f75844SAndroid Build Coastguard Worker     return -1;
98*d9f75844SAndroid Build Coastguard Worker   }
99*d9f75844SAndroid Build Coastguard Worker   // Reinitialize internal state for the frequencies and sample rates.
100*d9f75844SAndroid Build Coastguard Worker   num_channels_ = num_channels;
101*d9f75844SAndroid Build Coastguard Worker   my_mode_ = mode;
102*d9f75844SAndroid Build Coastguard Worker 
103*d9f75844SAndroid Build Coastguard Worker   if (state1_) {
104*d9f75844SAndroid Build Coastguard Worker     free(state1_);
105*d9f75844SAndroid Build Coastguard Worker     state1_ = nullptr;
106*d9f75844SAndroid Build Coastguard Worker   }
107*d9f75844SAndroid Build Coastguard Worker   if (state2_) {
108*d9f75844SAndroid Build Coastguard Worker     free(state2_);
109*d9f75844SAndroid Build Coastguard Worker     state2_ = nullptr;
110*d9f75844SAndroid Build Coastguard Worker   }
111*d9f75844SAndroid Build Coastguard Worker   if (state3_) {
112*d9f75844SAndroid Build Coastguard Worker     free(state3_);
113*d9f75844SAndroid Build Coastguard Worker     state3_ = nullptr;
114*d9f75844SAndroid Build Coastguard Worker   }
115*d9f75844SAndroid Build Coastguard Worker   if (in_buffer_) {
116*d9f75844SAndroid Build Coastguard Worker     free(in_buffer_);
117*d9f75844SAndroid Build Coastguard Worker     in_buffer_ = nullptr;
118*d9f75844SAndroid Build Coastguard Worker   }
119*d9f75844SAndroid Build Coastguard Worker   if (out_buffer_) {
120*d9f75844SAndroid Build Coastguard Worker     free(out_buffer_);
121*d9f75844SAndroid Build Coastguard Worker     out_buffer_ = nullptr;
122*d9f75844SAndroid Build Coastguard Worker   }
123*d9f75844SAndroid Build Coastguard Worker   if (helper_left_) {
124*d9f75844SAndroid Build Coastguard Worker     delete helper_left_;
125*d9f75844SAndroid Build Coastguard Worker     helper_left_ = nullptr;
126*d9f75844SAndroid Build Coastguard Worker   }
127*d9f75844SAndroid Build Coastguard Worker   if (helper_right_) {
128*d9f75844SAndroid Build Coastguard Worker     delete helper_right_;
129*d9f75844SAndroid Build Coastguard Worker     helper_right_ = nullptr;
130*d9f75844SAndroid Build Coastguard Worker   }
131*d9f75844SAndroid Build Coastguard Worker 
132*d9f75844SAndroid Build Coastguard Worker   in_buffer_size_ = 0;
133*d9f75844SAndroid Build Coastguard Worker   out_buffer_size_ = 0;
134*d9f75844SAndroid Build Coastguard Worker   in_buffer_size_max_ = 0;
135*d9f75844SAndroid Build Coastguard Worker   out_buffer_size_max_ = 0;
136*d9f75844SAndroid Build Coastguard Worker 
137*d9f75844SAndroid Build Coastguard Worker   // We need to track what domain we're in.
138*d9f75844SAndroid Build Coastguard Worker   my_in_frequency_khz_ = inFreq / 1000;
139*d9f75844SAndroid Build Coastguard Worker   my_out_frequency_khz_ = outFreq / 1000;
140*d9f75844SAndroid Build Coastguard Worker 
141*d9f75844SAndroid Build Coastguard Worker   if (num_channels_ == 2) {
142*d9f75844SAndroid Build Coastguard Worker     // Create two mono resamplers.
143*d9f75844SAndroid Build Coastguard Worker     helper_left_ = new Resampler(inFreq, outFreq, 1);
144*d9f75844SAndroid Build Coastguard Worker     helper_right_ = new Resampler(inFreq, outFreq, 1);
145*d9f75844SAndroid Build Coastguard Worker   }
146*d9f75844SAndroid Build Coastguard Worker 
147*d9f75844SAndroid Build Coastguard Worker   // Now create the states we need.
148*d9f75844SAndroid Build Coastguard Worker   switch (my_mode_) {
149*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode1To1:
150*d9f75844SAndroid Build Coastguard Worker       // No state needed;
151*d9f75844SAndroid Build Coastguard Worker       break;
152*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode1To2:
153*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(8 * sizeof(int32_t));
154*d9f75844SAndroid Build Coastguard Worker       memset(state1_, 0, 8 * sizeof(int32_t));
155*d9f75844SAndroid Build Coastguard Worker       break;
156*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode1To3:
157*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
158*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_ResetResample16khzTo48khz(
159*d9f75844SAndroid Build Coastguard Worker           static_cast<WebRtcSpl_State16khzTo48khz*>(state1_));
160*d9f75844SAndroid Build Coastguard Worker       break;
161*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode1To4:
162*d9f75844SAndroid Build Coastguard Worker       // 1:2
163*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(8 * sizeof(int32_t));
164*d9f75844SAndroid Build Coastguard Worker       memset(state1_, 0, 8 * sizeof(int32_t));
165*d9f75844SAndroid Build Coastguard Worker       // 2:4
166*d9f75844SAndroid Build Coastguard Worker       state2_ = malloc(8 * sizeof(int32_t));
167*d9f75844SAndroid Build Coastguard Worker       memset(state2_, 0, 8 * sizeof(int32_t));
168*d9f75844SAndroid Build Coastguard Worker       break;
169*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode1To6:
170*d9f75844SAndroid Build Coastguard Worker       // 1:2
171*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(8 * sizeof(int32_t));
172*d9f75844SAndroid Build Coastguard Worker       memset(state1_, 0, 8 * sizeof(int32_t));
173*d9f75844SAndroid Build Coastguard Worker       // 2:6
174*d9f75844SAndroid Build Coastguard Worker       state2_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
175*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_ResetResample16khzTo48khz(
176*d9f75844SAndroid Build Coastguard Worker           static_cast<WebRtcSpl_State16khzTo48khz*>(state2_));
177*d9f75844SAndroid Build Coastguard Worker       break;
178*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode1To12:
179*d9f75844SAndroid Build Coastguard Worker       // 1:2
180*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(8 * sizeof(int32_t));
181*d9f75844SAndroid Build Coastguard Worker       memset(state1_, 0, 8 * sizeof(int32_t));
182*d9f75844SAndroid Build Coastguard Worker       // 2:4
183*d9f75844SAndroid Build Coastguard Worker       state2_ = malloc(8 * sizeof(int32_t));
184*d9f75844SAndroid Build Coastguard Worker       memset(state2_, 0, 8 * sizeof(int32_t));
185*d9f75844SAndroid Build Coastguard Worker       // 4:12
186*d9f75844SAndroid Build Coastguard Worker       state3_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
187*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_ResetResample16khzTo48khz(
188*d9f75844SAndroid Build Coastguard Worker           static_cast<WebRtcSpl_State16khzTo48khz*>(state3_));
189*d9f75844SAndroid Build Coastguard Worker       break;
190*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode2To3:
191*d9f75844SAndroid Build Coastguard Worker       // 2:6
192*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
193*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_ResetResample16khzTo48khz(
194*d9f75844SAndroid Build Coastguard Worker           static_cast<WebRtcSpl_State16khzTo48khz*>(state1_));
195*d9f75844SAndroid Build Coastguard Worker       // 6:3
196*d9f75844SAndroid Build Coastguard Worker       state2_ = malloc(8 * sizeof(int32_t));
197*d9f75844SAndroid Build Coastguard Worker       memset(state2_, 0, 8 * sizeof(int32_t));
198*d9f75844SAndroid Build Coastguard Worker       break;
199*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode2To11:
200*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(8 * sizeof(int32_t));
201*d9f75844SAndroid Build Coastguard Worker       memset(state1_, 0, 8 * sizeof(int32_t));
202*d9f75844SAndroid Build Coastguard Worker 
203*d9f75844SAndroid Build Coastguard Worker       state2_ = malloc(sizeof(WebRtcSpl_State8khzTo22khz));
204*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_ResetResample8khzTo22khz(
205*d9f75844SAndroid Build Coastguard Worker           static_cast<WebRtcSpl_State8khzTo22khz*>(state2_));
206*d9f75844SAndroid Build Coastguard Worker       break;
207*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode4To11:
208*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(sizeof(WebRtcSpl_State8khzTo22khz));
209*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_ResetResample8khzTo22khz(
210*d9f75844SAndroid Build Coastguard Worker           static_cast<WebRtcSpl_State8khzTo22khz*>(state1_));
211*d9f75844SAndroid Build Coastguard Worker       break;
212*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode8To11:
213*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(sizeof(WebRtcSpl_State16khzTo22khz));
214*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_ResetResample16khzTo22khz(
215*d9f75844SAndroid Build Coastguard Worker           static_cast<WebRtcSpl_State16khzTo22khz*>(state1_));
216*d9f75844SAndroid Build Coastguard Worker       break;
217*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode11To16:
218*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(8 * sizeof(int32_t));
219*d9f75844SAndroid Build Coastguard Worker       memset(state1_, 0, 8 * sizeof(int32_t));
220*d9f75844SAndroid Build Coastguard Worker 
221*d9f75844SAndroid Build Coastguard Worker       state2_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz));
222*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_ResetResample22khzTo16khz(
223*d9f75844SAndroid Build Coastguard Worker           static_cast<WebRtcSpl_State22khzTo16khz*>(state2_));
224*d9f75844SAndroid Build Coastguard Worker       break;
225*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode11To32:
226*d9f75844SAndroid Build Coastguard Worker       // 11 -> 22
227*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(8 * sizeof(int32_t));
228*d9f75844SAndroid Build Coastguard Worker       memset(state1_, 0, 8 * sizeof(int32_t));
229*d9f75844SAndroid Build Coastguard Worker 
230*d9f75844SAndroid Build Coastguard Worker       // 22 -> 16
231*d9f75844SAndroid Build Coastguard Worker       state2_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz));
232*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_ResetResample22khzTo16khz(
233*d9f75844SAndroid Build Coastguard Worker           static_cast<WebRtcSpl_State22khzTo16khz*>(state2_));
234*d9f75844SAndroid Build Coastguard Worker 
235*d9f75844SAndroid Build Coastguard Worker       // 16 -> 32
236*d9f75844SAndroid Build Coastguard Worker       state3_ = malloc(8 * sizeof(int32_t));
237*d9f75844SAndroid Build Coastguard Worker       memset(state3_, 0, 8 * sizeof(int32_t));
238*d9f75844SAndroid Build Coastguard Worker 
239*d9f75844SAndroid Build Coastguard Worker       break;
240*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode2To1:
241*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(8 * sizeof(int32_t));
242*d9f75844SAndroid Build Coastguard Worker       memset(state1_, 0, 8 * sizeof(int32_t));
243*d9f75844SAndroid Build Coastguard Worker       break;
244*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode3To1:
245*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
246*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_ResetResample48khzTo16khz(
247*d9f75844SAndroid Build Coastguard Worker           static_cast<WebRtcSpl_State48khzTo16khz*>(state1_));
248*d9f75844SAndroid Build Coastguard Worker       break;
249*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode4To1:
250*d9f75844SAndroid Build Coastguard Worker       // 4:2
251*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(8 * sizeof(int32_t));
252*d9f75844SAndroid Build Coastguard Worker       memset(state1_, 0, 8 * sizeof(int32_t));
253*d9f75844SAndroid Build Coastguard Worker       // 2:1
254*d9f75844SAndroid Build Coastguard Worker       state2_ = malloc(8 * sizeof(int32_t));
255*d9f75844SAndroid Build Coastguard Worker       memset(state2_, 0, 8 * sizeof(int32_t));
256*d9f75844SAndroid Build Coastguard Worker       break;
257*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode6To1:
258*d9f75844SAndroid Build Coastguard Worker       // 6:2
259*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
260*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_ResetResample48khzTo16khz(
261*d9f75844SAndroid Build Coastguard Worker           static_cast<WebRtcSpl_State48khzTo16khz*>(state1_));
262*d9f75844SAndroid Build Coastguard Worker       // 2:1
263*d9f75844SAndroid Build Coastguard Worker       state2_ = malloc(8 * sizeof(int32_t));
264*d9f75844SAndroid Build Coastguard Worker       memset(state2_, 0, 8 * sizeof(int32_t));
265*d9f75844SAndroid Build Coastguard Worker       break;
266*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode12To1:
267*d9f75844SAndroid Build Coastguard Worker       // 12:4
268*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
269*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_ResetResample48khzTo16khz(
270*d9f75844SAndroid Build Coastguard Worker           static_cast<WebRtcSpl_State48khzTo16khz*>(state1_));
271*d9f75844SAndroid Build Coastguard Worker       // 4:2
272*d9f75844SAndroid Build Coastguard Worker       state2_ = malloc(8 * sizeof(int32_t));
273*d9f75844SAndroid Build Coastguard Worker       memset(state2_, 0, 8 * sizeof(int32_t));
274*d9f75844SAndroid Build Coastguard Worker       // 2:1
275*d9f75844SAndroid Build Coastguard Worker       state3_ = malloc(8 * sizeof(int32_t));
276*d9f75844SAndroid Build Coastguard Worker       memset(state3_, 0, 8 * sizeof(int32_t));
277*d9f75844SAndroid Build Coastguard Worker       break;
278*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode3To2:
279*d9f75844SAndroid Build Coastguard Worker       // 3:6
280*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(8 * sizeof(int32_t));
281*d9f75844SAndroid Build Coastguard Worker       memset(state1_, 0, 8 * sizeof(int32_t));
282*d9f75844SAndroid Build Coastguard Worker       // 6:2
283*d9f75844SAndroid Build Coastguard Worker       state2_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
284*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_ResetResample48khzTo16khz(
285*d9f75844SAndroid Build Coastguard Worker           static_cast<WebRtcSpl_State48khzTo16khz*>(state2_));
286*d9f75844SAndroid Build Coastguard Worker       break;
287*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode11To2:
288*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(sizeof(WebRtcSpl_State22khzTo8khz));
289*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_ResetResample22khzTo8khz(
290*d9f75844SAndroid Build Coastguard Worker           static_cast<WebRtcSpl_State22khzTo8khz*>(state1_));
291*d9f75844SAndroid Build Coastguard Worker 
292*d9f75844SAndroid Build Coastguard Worker       state2_ = malloc(8 * sizeof(int32_t));
293*d9f75844SAndroid Build Coastguard Worker       memset(state2_, 0, 8 * sizeof(int32_t));
294*d9f75844SAndroid Build Coastguard Worker 
295*d9f75844SAndroid Build Coastguard Worker       break;
296*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode11To4:
297*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(sizeof(WebRtcSpl_State22khzTo8khz));
298*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_ResetResample22khzTo8khz(
299*d9f75844SAndroid Build Coastguard Worker           static_cast<WebRtcSpl_State22khzTo8khz*>(state1_));
300*d9f75844SAndroid Build Coastguard Worker       break;
301*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode11To8:
302*d9f75844SAndroid Build Coastguard Worker       state1_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz));
303*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_ResetResample22khzTo16khz(
304*d9f75844SAndroid Build Coastguard Worker           static_cast<WebRtcSpl_State22khzTo16khz*>(state1_));
305*d9f75844SAndroid Build Coastguard Worker       break;
306*d9f75844SAndroid Build Coastguard Worker   }
307*d9f75844SAndroid Build Coastguard Worker 
308*d9f75844SAndroid Build Coastguard Worker   return 0;
309*d9f75844SAndroid Build Coastguard Worker }
310*d9f75844SAndroid Build Coastguard Worker 
ComputeResamplerMode(int in_freq_hz,int out_freq_hz,ResamplerMode * mode)311*d9f75844SAndroid Build Coastguard Worker int Resampler::ComputeResamplerMode(int in_freq_hz,
312*d9f75844SAndroid Build Coastguard Worker                                     int out_freq_hz,
313*d9f75844SAndroid Build Coastguard Worker                                     ResamplerMode* mode) {
314*d9f75844SAndroid Build Coastguard Worker   // Start with a math exercise, Euclid's algorithm to find the gcd:
315*d9f75844SAndroid Build Coastguard Worker   int a = in_freq_hz;
316*d9f75844SAndroid Build Coastguard Worker   int b = out_freq_hz;
317*d9f75844SAndroid Build Coastguard Worker   int c = a % b;
318*d9f75844SAndroid Build Coastguard Worker   while (c != 0) {
319*d9f75844SAndroid Build Coastguard Worker     a = b;
320*d9f75844SAndroid Build Coastguard Worker     b = c;
321*d9f75844SAndroid Build Coastguard Worker     c = a % b;
322*d9f75844SAndroid Build Coastguard Worker   }
323*d9f75844SAndroid Build Coastguard Worker   // b is now the gcd;
324*d9f75844SAndroid Build Coastguard Worker 
325*d9f75844SAndroid Build Coastguard Worker   // Scale with GCD
326*d9f75844SAndroid Build Coastguard Worker   const int reduced_in_freq = in_freq_hz / b;
327*d9f75844SAndroid Build Coastguard Worker   const int reduced_out_freq = out_freq_hz / b;
328*d9f75844SAndroid Build Coastguard Worker 
329*d9f75844SAndroid Build Coastguard Worker   if (reduced_in_freq == reduced_out_freq) {
330*d9f75844SAndroid Build Coastguard Worker     *mode = kResamplerMode1To1;
331*d9f75844SAndroid Build Coastguard Worker   } else if (reduced_in_freq == 1) {
332*d9f75844SAndroid Build Coastguard Worker     switch (reduced_out_freq) {
333*d9f75844SAndroid Build Coastguard Worker       case 2:
334*d9f75844SAndroid Build Coastguard Worker         *mode = kResamplerMode1To2;
335*d9f75844SAndroid Build Coastguard Worker         break;
336*d9f75844SAndroid Build Coastguard Worker       case 3:
337*d9f75844SAndroid Build Coastguard Worker         *mode = kResamplerMode1To3;
338*d9f75844SAndroid Build Coastguard Worker         break;
339*d9f75844SAndroid Build Coastguard Worker       case 4:
340*d9f75844SAndroid Build Coastguard Worker         *mode = kResamplerMode1To4;
341*d9f75844SAndroid Build Coastguard Worker         break;
342*d9f75844SAndroid Build Coastguard Worker       case 6:
343*d9f75844SAndroid Build Coastguard Worker         *mode = kResamplerMode1To6;
344*d9f75844SAndroid Build Coastguard Worker         break;
345*d9f75844SAndroid Build Coastguard Worker       case 12:
346*d9f75844SAndroid Build Coastguard Worker         *mode = kResamplerMode1To12;
347*d9f75844SAndroid Build Coastguard Worker         break;
348*d9f75844SAndroid Build Coastguard Worker       default:
349*d9f75844SAndroid Build Coastguard Worker         return -1;
350*d9f75844SAndroid Build Coastguard Worker     }
351*d9f75844SAndroid Build Coastguard Worker   } else if (reduced_out_freq == 1) {
352*d9f75844SAndroid Build Coastguard Worker     switch (reduced_in_freq) {
353*d9f75844SAndroid Build Coastguard Worker       case 2:
354*d9f75844SAndroid Build Coastguard Worker         *mode = kResamplerMode2To1;
355*d9f75844SAndroid Build Coastguard Worker         break;
356*d9f75844SAndroid Build Coastguard Worker       case 3:
357*d9f75844SAndroid Build Coastguard Worker         *mode = kResamplerMode3To1;
358*d9f75844SAndroid Build Coastguard Worker         break;
359*d9f75844SAndroid Build Coastguard Worker       case 4:
360*d9f75844SAndroid Build Coastguard Worker         *mode = kResamplerMode4To1;
361*d9f75844SAndroid Build Coastguard Worker         break;
362*d9f75844SAndroid Build Coastguard Worker       case 6:
363*d9f75844SAndroid Build Coastguard Worker         *mode = kResamplerMode6To1;
364*d9f75844SAndroid Build Coastguard Worker         break;
365*d9f75844SAndroid Build Coastguard Worker       case 12:
366*d9f75844SAndroid Build Coastguard Worker         *mode = kResamplerMode12To1;
367*d9f75844SAndroid Build Coastguard Worker         break;
368*d9f75844SAndroid Build Coastguard Worker       default:
369*d9f75844SAndroid Build Coastguard Worker         return -1;
370*d9f75844SAndroid Build Coastguard Worker     }
371*d9f75844SAndroid Build Coastguard Worker   } else if ((reduced_in_freq == 2) && (reduced_out_freq == 3)) {
372*d9f75844SAndroid Build Coastguard Worker     *mode = kResamplerMode2To3;
373*d9f75844SAndroid Build Coastguard Worker   } else if ((reduced_in_freq == 2) && (reduced_out_freq == 11)) {
374*d9f75844SAndroid Build Coastguard Worker     *mode = kResamplerMode2To11;
375*d9f75844SAndroid Build Coastguard Worker   } else if ((reduced_in_freq == 4) && (reduced_out_freq == 11)) {
376*d9f75844SAndroid Build Coastguard Worker     *mode = kResamplerMode4To11;
377*d9f75844SAndroid Build Coastguard Worker   } else if ((reduced_in_freq == 8) && (reduced_out_freq == 11)) {
378*d9f75844SAndroid Build Coastguard Worker     *mode = kResamplerMode8To11;
379*d9f75844SAndroid Build Coastguard Worker   } else if ((reduced_in_freq == 3) && (reduced_out_freq == 2)) {
380*d9f75844SAndroid Build Coastguard Worker     *mode = kResamplerMode3To2;
381*d9f75844SAndroid Build Coastguard Worker   } else if ((reduced_in_freq == 11) && (reduced_out_freq == 2)) {
382*d9f75844SAndroid Build Coastguard Worker     *mode = kResamplerMode11To2;
383*d9f75844SAndroid Build Coastguard Worker   } else if ((reduced_in_freq == 11) && (reduced_out_freq == 4)) {
384*d9f75844SAndroid Build Coastguard Worker     *mode = kResamplerMode11To4;
385*d9f75844SAndroid Build Coastguard Worker   } else if ((reduced_in_freq == 11) && (reduced_out_freq == 16)) {
386*d9f75844SAndroid Build Coastguard Worker     *mode = kResamplerMode11To16;
387*d9f75844SAndroid Build Coastguard Worker   } else if ((reduced_in_freq == 11) && (reduced_out_freq == 32)) {
388*d9f75844SAndroid Build Coastguard Worker     *mode = kResamplerMode11To32;
389*d9f75844SAndroid Build Coastguard Worker   } else if ((reduced_in_freq == 11) && (reduced_out_freq == 8)) {
390*d9f75844SAndroid Build Coastguard Worker     *mode = kResamplerMode11To8;
391*d9f75844SAndroid Build Coastguard Worker   } else {
392*d9f75844SAndroid Build Coastguard Worker     return -1;
393*d9f75844SAndroid Build Coastguard Worker   }
394*d9f75844SAndroid Build Coastguard Worker   return 0;
395*d9f75844SAndroid Build Coastguard Worker }
396*d9f75844SAndroid Build Coastguard Worker 
397*d9f75844SAndroid Build Coastguard Worker // Synchronous resampling, all output samples are written to samplesOut
Push(const int16_t * samplesIn,size_t lengthIn,int16_t * samplesOut,size_t maxLen,size_t & outLen)398*d9f75844SAndroid Build Coastguard Worker int Resampler::Push(const int16_t* samplesIn,
399*d9f75844SAndroid Build Coastguard Worker                     size_t lengthIn,
400*d9f75844SAndroid Build Coastguard Worker                     int16_t* samplesOut,
401*d9f75844SAndroid Build Coastguard Worker                     size_t maxLen,
402*d9f75844SAndroid Build Coastguard Worker                     size_t& outLen) {
403*d9f75844SAndroid Build Coastguard Worker   if (num_channels_ == 2) {
404*d9f75844SAndroid Build Coastguard Worker     // Split up the signal and call the helper object for each channel
405*d9f75844SAndroid Build Coastguard Worker     int16_t* left =
406*d9f75844SAndroid Build Coastguard Worker         static_cast<int16_t*>(malloc(lengthIn * sizeof(int16_t) / 2));
407*d9f75844SAndroid Build Coastguard Worker     int16_t* right =
408*d9f75844SAndroid Build Coastguard Worker         static_cast<int16_t*>(malloc(lengthIn * sizeof(int16_t) / 2));
409*d9f75844SAndroid Build Coastguard Worker     int16_t* out_left =
410*d9f75844SAndroid Build Coastguard Worker         static_cast<int16_t*>(malloc(maxLen / 2 * sizeof(int16_t)));
411*d9f75844SAndroid Build Coastguard Worker     int16_t* out_right =
412*d9f75844SAndroid Build Coastguard Worker         static_cast<int16_t*>(malloc(maxLen / 2 * sizeof(int16_t)));
413*d9f75844SAndroid Build Coastguard Worker     int res = 0;
414*d9f75844SAndroid Build Coastguard Worker     for (size_t i = 0; i < lengthIn; i += 2) {
415*d9f75844SAndroid Build Coastguard Worker       left[i >> 1] = samplesIn[i];
416*d9f75844SAndroid Build Coastguard Worker       right[i >> 1] = samplesIn[i + 1];
417*d9f75844SAndroid Build Coastguard Worker     }
418*d9f75844SAndroid Build Coastguard Worker 
419*d9f75844SAndroid Build Coastguard Worker     // It's OK to overwrite the local parameter, since it's just a copy
420*d9f75844SAndroid Build Coastguard Worker     lengthIn = lengthIn / 2;
421*d9f75844SAndroid Build Coastguard Worker 
422*d9f75844SAndroid Build Coastguard Worker     size_t actualOutLen_left = 0;
423*d9f75844SAndroid Build Coastguard Worker     size_t actualOutLen_right = 0;
424*d9f75844SAndroid Build Coastguard Worker     // Do resampling for right channel
425*d9f75844SAndroid Build Coastguard Worker     res |= helper_left_->Push(left, lengthIn, out_left, maxLen / 2,
426*d9f75844SAndroid Build Coastguard Worker                               actualOutLen_left);
427*d9f75844SAndroid Build Coastguard Worker     res |= helper_right_->Push(right, lengthIn, out_right, maxLen / 2,
428*d9f75844SAndroid Build Coastguard Worker                                actualOutLen_right);
429*d9f75844SAndroid Build Coastguard Worker     if (res || (actualOutLen_left != actualOutLen_right)) {
430*d9f75844SAndroid Build Coastguard Worker       free(left);
431*d9f75844SAndroid Build Coastguard Worker       free(right);
432*d9f75844SAndroid Build Coastguard Worker       free(out_left);
433*d9f75844SAndroid Build Coastguard Worker       free(out_right);
434*d9f75844SAndroid Build Coastguard Worker       return -1;
435*d9f75844SAndroid Build Coastguard Worker     }
436*d9f75844SAndroid Build Coastguard Worker 
437*d9f75844SAndroid Build Coastguard Worker     // Reassemble the signal
438*d9f75844SAndroid Build Coastguard Worker     for (size_t i = 0; i < actualOutLen_left; i++) {
439*d9f75844SAndroid Build Coastguard Worker       samplesOut[i * 2] = out_left[i];
440*d9f75844SAndroid Build Coastguard Worker       samplesOut[i * 2 + 1] = out_right[i];
441*d9f75844SAndroid Build Coastguard Worker     }
442*d9f75844SAndroid Build Coastguard Worker     outLen = 2 * actualOutLen_left;
443*d9f75844SAndroid Build Coastguard Worker 
444*d9f75844SAndroid Build Coastguard Worker     free(left);
445*d9f75844SAndroid Build Coastguard Worker     free(right);
446*d9f75844SAndroid Build Coastguard Worker     free(out_left);
447*d9f75844SAndroid Build Coastguard Worker     free(out_right);
448*d9f75844SAndroid Build Coastguard Worker 
449*d9f75844SAndroid Build Coastguard Worker     return 0;
450*d9f75844SAndroid Build Coastguard Worker   }
451*d9f75844SAndroid Build Coastguard Worker 
452*d9f75844SAndroid Build Coastguard Worker   // Containers for temp samples
453*d9f75844SAndroid Build Coastguard Worker   int16_t* tmp;
454*d9f75844SAndroid Build Coastguard Worker   int16_t* tmp_2;
455*d9f75844SAndroid Build Coastguard Worker   // tmp data for resampling routines
456*d9f75844SAndroid Build Coastguard Worker   int32_t* tmp_mem;
457*d9f75844SAndroid Build Coastguard Worker 
458*d9f75844SAndroid Build Coastguard Worker   switch (my_mode_) {
459*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode1To1:
460*d9f75844SAndroid Build Coastguard Worker       memcpy(samplesOut, samplesIn, lengthIn * sizeof(int16_t));
461*d9f75844SAndroid Build Coastguard Worker       outLen = lengthIn;
462*d9f75844SAndroid Build Coastguard Worker       break;
463*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode1To2:
464*d9f75844SAndroid Build Coastguard Worker       if (maxLen < (lengthIn * 2)) {
465*d9f75844SAndroid Build Coastguard Worker         return -1;
466*d9f75844SAndroid Build Coastguard Worker       }
467*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut,
468*d9f75844SAndroid Build Coastguard Worker                             static_cast<int32_t*>(state1_));
469*d9f75844SAndroid Build Coastguard Worker       outLen = lengthIn * 2;
470*d9f75844SAndroid Build Coastguard Worker       return 0;
471*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode1To3:
472*d9f75844SAndroid Build Coastguard Worker 
473*d9f75844SAndroid Build Coastguard Worker       // We can only handle blocks of 160 samples
474*d9f75844SAndroid Build Coastguard Worker       // Can be fixed, but I don't think it's needed
475*d9f75844SAndroid Build Coastguard Worker       if ((lengthIn % 160) != 0) {
476*d9f75844SAndroid Build Coastguard Worker         return -1;
477*d9f75844SAndroid Build Coastguard Worker       }
478*d9f75844SAndroid Build Coastguard Worker       if (maxLen < (lengthIn * 3)) {
479*d9f75844SAndroid Build Coastguard Worker         return -1;
480*d9f75844SAndroid Build Coastguard Worker       }
481*d9f75844SAndroid Build Coastguard Worker       tmp_mem = static_cast<int32_t*>(malloc(336 * sizeof(int32_t)));
482*d9f75844SAndroid Build Coastguard Worker 
483*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < lengthIn; i += 160) {
484*d9f75844SAndroid Build Coastguard Worker         WebRtcSpl_Resample16khzTo48khz(
485*d9f75844SAndroid Build Coastguard Worker             samplesIn + i, samplesOut + i * 3,
486*d9f75844SAndroid Build Coastguard Worker             static_cast<WebRtcSpl_State16khzTo48khz*>(state1_), tmp_mem);
487*d9f75844SAndroid Build Coastguard Worker       }
488*d9f75844SAndroid Build Coastguard Worker       outLen = lengthIn * 3;
489*d9f75844SAndroid Build Coastguard Worker       free(tmp_mem);
490*d9f75844SAndroid Build Coastguard Worker       return 0;
491*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode1To4:
492*d9f75844SAndroid Build Coastguard Worker       if (maxLen < (lengthIn * 4)) {
493*d9f75844SAndroid Build Coastguard Worker         return -1;
494*d9f75844SAndroid Build Coastguard Worker       }
495*d9f75844SAndroid Build Coastguard Worker 
496*d9f75844SAndroid Build Coastguard Worker       tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * 2 * lengthIn));
497*d9f75844SAndroid Build Coastguard Worker       // 1:2
498*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp,
499*d9f75844SAndroid Build Coastguard Worker                             static_cast<int32_t*>(state1_));
500*d9f75844SAndroid Build Coastguard Worker       // 2:4
501*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_UpsampleBy2(tmp, lengthIn * 2, samplesOut,
502*d9f75844SAndroid Build Coastguard Worker                             static_cast<int32_t*>(state2_));
503*d9f75844SAndroid Build Coastguard Worker       outLen = lengthIn * 4;
504*d9f75844SAndroid Build Coastguard Worker       free(tmp);
505*d9f75844SAndroid Build Coastguard Worker       return 0;
506*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode1To6:
507*d9f75844SAndroid Build Coastguard Worker       // We can only handle blocks of 80 samples
508*d9f75844SAndroid Build Coastguard Worker       // Can be fixed, but I don't think it's needed
509*d9f75844SAndroid Build Coastguard Worker       if ((lengthIn % 80) != 0) {
510*d9f75844SAndroid Build Coastguard Worker         return -1;
511*d9f75844SAndroid Build Coastguard Worker       }
512*d9f75844SAndroid Build Coastguard Worker       if (maxLen < (lengthIn * 6)) {
513*d9f75844SAndroid Build Coastguard Worker         return -1;
514*d9f75844SAndroid Build Coastguard Worker       }
515*d9f75844SAndroid Build Coastguard Worker 
516*d9f75844SAndroid Build Coastguard Worker       // 1:2
517*d9f75844SAndroid Build Coastguard Worker 
518*d9f75844SAndroid Build Coastguard Worker       tmp_mem = static_cast<int32_t*>(malloc(336 * sizeof(int32_t)));
519*d9f75844SAndroid Build Coastguard Worker       tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * 2 * lengthIn));
520*d9f75844SAndroid Build Coastguard Worker 
521*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp,
522*d9f75844SAndroid Build Coastguard Worker                             static_cast<int32_t*>(state1_));
523*d9f75844SAndroid Build Coastguard Worker       outLen = lengthIn * 2;
524*d9f75844SAndroid Build Coastguard Worker 
525*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < outLen; i += 160) {
526*d9f75844SAndroid Build Coastguard Worker         WebRtcSpl_Resample16khzTo48khz(
527*d9f75844SAndroid Build Coastguard Worker             tmp + i, samplesOut + i * 3,
528*d9f75844SAndroid Build Coastguard Worker             static_cast<WebRtcSpl_State16khzTo48khz*>(state2_), tmp_mem);
529*d9f75844SAndroid Build Coastguard Worker       }
530*d9f75844SAndroid Build Coastguard Worker       outLen = outLen * 3;
531*d9f75844SAndroid Build Coastguard Worker       free(tmp_mem);
532*d9f75844SAndroid Build Coastguard Worker       free(tmp);
533*d9f75844SAndroid Build Coastguard Worker 
534*d9f75844SAndroid Build Coastguard Worker       return 0;
535*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode1To12:
536*d9f75844SAndroid Build Coastguard Worker       // We can only handle blocks of 40 samples
537*d9f75844SAndroid Build Coastguard Worker       // Can be fixed, but I don't think it's needed
538*d9f75844SAndroid Build Coastguard Worker       if ((lengthIn % 40) != 0) {
539*d9f75844SAndroid Build Coastguard Worker         return -1;
540*d9f75844SAndroid Build Coastguard Worker       }
541*d9f75844SAndroid Build Coastguard Worker       if (maxLen < (lengthIn * 12)) {
542*d9f75844SAndroid Build Coastguard Worker         return -1;
543*d9f75844SAndroid Build Coastguard Worker       }
544*d9f75844SAndroid Build Coastguard Worker 
545*d9f75844SAndroid Build Coastguard Worker       tmp_mem = static_cast<int32_t*>(malloc(336 * sizeof(int32_t)));
546*d9f75844SAndroid Build Coastguard Worker       tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * 4 * lengthIn));
547*d9f75844SAndroid Build Coastguard Worker       // 1:2
548*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut,
549*d9f75844SAndroid Build Coastguard Worker                             static_cast<int32_t*>(state1_));
550*d9f75844SAndroid Build Coastguard Worker       outLen = lengthIn * 2;
551*d9f75844SAndroid Build Coastguard Worker       // 2:4
552*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_UpsampleBy2(samplesOut, outLen, tmp,
553*d9f75844SAndroid Build Coastguard Worker                             static_cast<int32_t*>(state2_));
554*d9f75844SAndroid Build Coastguard Worker       outLen = outLen * 2;
555*d9f75844SAndroid Build Coastguard Worker       // 4:12
556*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < outLen; i += 160) {
557*d9f75844SAndroid Build Coastguard Worker         // WebRtcSpl_Resample16khzTo48khz() takes a block of 160 samples
558*d9f75844SAndroid Build Coastguard Worker         // as input and outputs a resampled block of 480 samples. The
559*d9f75844SAndroid Build Coastguard Worker         // data is now actually in 32 kHz sampling rate, despite the
560*d9f75844SAndroid Build Coastguard Worker         // function name, and with a resampling factor of three becomes
561*d9f75844SAndroid Build Coastguard Worker         // 96 kHz.
562*d9f75844SAndroid Build Coastguard Worker         WebRtcSpl_Resample16khzTo48khz(
563*d9f75844SAndroid Build Coastguard Worker             tmp + i, samplesOut + i * 3,
564*d9f75844SAndroid Build Coastguard Worker             static_cast<WebRtcSpl_State16khzTo48khz*>(state3_), tmp_mem);
565*d9f75844SAndroid Build Coastguard Worker       }
566*d9f75844SAndroid Build Coastguard Worker       outLen = outLen * 3;
567*d9f75844SAndroid Build Coastguard Worker       free(tmp_mem);
568*d9f75844SAndroid Build Coastguard Worker       free(tmp);
569*d9f75844SAndroid Build Coastguard Worker 
570*d9f75844SAndroid Build Coastguard Worker       return 0;
571*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode2To3:
572*d9f75844SAndroid Build Coastguard Worker       if (maxLen < (lengthIn * 3 / 2)) {
573*d9f75844SAndroid Build Coastguard Worker         return -1;
574*d9f75844SAndroid Build Coastguard Worker       }
575*d9f75844SAndroid Build Coastguard Worker       // 2:6
576*d9f75844SAndroid Build Coastguard Worker       // We can only handle blocks of 160 samples
577*d9f75844SAndroid Build Coastguard Worker       // Can be fixed, but I don't think it's needed
578*d9f75844SAndroid Build Coastguard Worker       if ((lengthIn % 160) != 0) {
579*d9f75844SAndroid Build Coastguard Worker         return -1;
580*d9f75844SAndroid Build Coastguard Worker       }
581*d9f75844SAndroid Build Coastguard Worker       tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * lengthIn * 3));
582*d9f75844SAndroid Build Coastguard Worker       tmp_mem = static_cast<int32_t*>(malloc(336 * sizeof(int32_t)));
583*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < lengthIn; i += 160) {
584*d9f75844SAndroid Build Coastguard Worker         WebRtcSpl_Resample16khzTo48khz(
585*d9f75844SAndroid Build Coastguard Worker             samplesIn + i, tmp + i * 3,
586*d9f75844SAndroid Build Coastguard Worker             static_cast<WebRtcSpl_State16khzTo48khz*>(state1_), tmp_mem);
587*d9f75844SAndroid Build Coastguard Worker       }
588*d9f75844SAndroid Build Coastguard Worker       lengthIn = lengthIn * 3;
589*d9f75844SAndroid Build Coastguard Worker       // 6:3
590*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut,
591*d9f75844SAndroid Build Coastguard Worker                               static_cast<int32_t*>(state2_));
592*d9f75844SAndroid Build Coastguard Worker       outLen = lengthIn / 2;
593*d9f75844SAndroid Build Coastguard Worker       free(tmp);
594*d9f75844SAndroid Build Coastguard Worker       free(tmp_mem);
595*d9f75844SAndroid Build Coastguard Worker       return 0;
596*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode2To11:
597*d9f75844SAndroid Build Coastguard Worker 
598*d9f75844SAndroid Build Coastguard Worker       // We can only handle blocks of 80 samples
599*d9f75844SAndroid Build Coastguard Worker       // Can be fixed, but I don't think it's needed
600*d9f75844SAndroid Build Coastguard Worker       if ((lengthIn % 80) != 0) {
601*d9f75844SAndroid Build Coastguard Worker         return -1;
602*d9f75844SAndroid Build Coastguard Worker       }
603*d9f75844SAndroid Build Coastguard Worker       if (maxLen < ((lengthIn * 11) / 2)) {
604*d9f75844SAndroid Build Coastguard Worker         return -1;
605*d9f75844SAndroid Build Coastguard Worker       }
606*d9f75844SAndroid Build Coastguard Worker       tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * 2 * lengthIn));
607*d9f75844SAndroid Build Coastguard Worker       // 1:2
608*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp,
609*d9f75844SAndroid Build Coastguard Worker                             static_cast<int32_t*>(state1_));
610*d9f75844SAndroid Build Coastguard Worker       lengthIn *= 2;
611*d9f75844SAndroid Build Coastguard Worker 
612*d9f75844SAndroid Build Coastguard Worker       tmp_mem = static_cast<int32_t*>(malloc(98 * sizeof(int32_t)));
613*d9f75844SAndroid Build Coastguard Worker 
614*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < lengthIn; i += 80) {
615*d9f75844SAndroid Build Coastguard Worker         WebRtcSpl_Resample8khzTo22khz(
616*d9f75844SAndroid Build Coastguard Worker             tmp + i, samplesOut + (i * 11) / 4,
617*d9f75844SAndroid Build Coastguard Worker             static_cast<WebRtcSpl_State8khzTo22khz*>(state2_), tmp_mem);
618*d9f75844SAndroid Build Coastguard Worker       }
619*d9f75844SAndroid Build Coastguard Worker       outLen = (lengthIn * 11) / 4;
620*d9f75844SAndroid Build Coastguard Worker       free(tmp_mem);
621*d9f75844SAndroid Build Coastguard Worker       free(tmp);
622*d9f75844SAndroid Build Coastguard Worker       return 0;
623*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode4To11:
624*d9f75844SAndroid Build Coastguard Worker 
625*d9f75844SAndroid Build Coastguard Worker       // We can only handle blocks of 80 samples
626*d9f75844SAndroid Build Coastguard Worker       // Can be fixed, but I don't think it's needed
627*d9f75844SAndroid Build Coastguard Worker       if ((lengthIn % 80) != 0) {
628*d9f75844SAndroid Build Coastguard Worker         return -1;
629*d9f75844SAndroid Build Coastguard Worker       }
630*d9f75844SAndroid Build Coastguard Worker       if (maxLen < ((lengthIn * 11) / 4)) {
631*d9f75844SAndroid Build Coastguard Worker         return -1;
632*d9f75844SAndroid Build Coastguard Worker       }
633*d9f75844SAndroid Build Coastguard Worker       tmp_mem = static_cast<int32_t*>(malloc(98 * sizeof(int32_t)));
634*d9f75844SAndroid Build Coastguard Worker 
635*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < lengthIn; i += 80) {
636*d9f75844SAndroid Build Coastguard Worker         WebRtcSpl_Resample8khzTo22khz(
637*d9f75844SAndroid Build Coastguard Worker             samplesIn + i, samplesOut + (i * 11) / 4,
638*d9f75844SAndroid Build Coastguard Worker             static_cast<WebRtcSpl_State8khzTo22khz*>(state1_), tmp_mem);
639*d9f75844SAndroid Build Coastguard Worker       }
640*d9f75844SAndroid Build Coastguard Worker       outLen = (lengthIn * 11) / 4;
641*d9f75844SAndroid Build Coastguard Worker       free(tmp_mem);
642*d9f75844SAndroid Build Coastguard Worker       return 0;
643*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode8To11:
644*d9f75844SAndroid Build Coastguard Worker       // We can only handle blocks of 160 samples
645*d9f75844SAndroid Build Coastguard Worker       // Can be fixed, but I don't think it's needed
646*d9f75844SAndroid Build Coastguard Worker       if ((lengthIn % 160) != 0) {
647*d9f75844SAndroid Build Coastguard Worker         return -1;
648*d9f75844SAndroid Build Coastguard Worker       }
649*d9f75844SAndroid Build Coastguard Worker       if (maxLen < ((lengthIn * 11) / 8)) {
650*d9f75844SAndroid Build Coastguard Worker         return -1;
651*d9f75844SAndroid Build Coastguard Worker       }
652*d9f75844SAndroid Build Coastguard Worker       tmp_mem = static_cast<int32_t*>(malloc(88 * sizeof(int32_t)));
653*d9f75844SAndroid Build Coastguard Worker 
654*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < lengthIn; i += 160) {
655*d9f75844SAndroid Build Coastguard Worker         WebRtcSpl_Resample16khzTo22khz(
656*d9f75844SAndroid Build Coastguard Worker             samplesIn + i, samplesOut + (i * 11) / 8,
657*d9f75844SAndroid Build Coastguard Worker             static_cast<WebRtcSpl_State16khzTo22khz*>(state1_), tmp_mem);
658*d9f75844SAndroid Build Coastguard Worker       }
659*d9f75844SAndroid Build Coastguard Worker       outLen = (lengthIn * 11) / 8;
660*d9f75844SAndroid Build Coastguard Worker       free(tmp_mem);
661*d9f75844SAndroid Build Coastguard Worker       return 0;
662*d9f75844SAndroid Build Coastguard Worker 
663*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode11To16:
664*d9f75844SAndroid Build Coastguard Worker       // We can only handle blocks of 110 samples
665*d9f75844SAndroid Build Coastguard Worker       if ((lengthIn % 110) != 0) {
666*d9f75844SAndroid Build Coastguard Worker         return -1;
667*d9f75844SAndroid Build Coastguard Worker       }
668*d9f75844SAndroid Build Coastguard Worker       if (maxLen < ((lengthIn * 16) / 11)) {
669*d9f75844SAndroid Build Coastguard Worker         return -1;
670*d9f75844SAndroid Build Coastguard Worker       }
671*d9f75844SAndroid Build Coastguard Worker 
672*d9f75844SAndroid Build Coastguard Worker       tmp_mem = static_cast<int32_t*>(malloc(104 * sizeof(int32_t)));
673*d9f75844SAndroid Build Coastguard Worker       tmp = static_cast<int16_t*>(malloc((sizeof(int16_t) * lengthIn * 2)));
674*d9f75844SAndroid Build Coastguard Worker 
675*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp,
676*d9f75844SAndroid Build Coastguard Worker                             static_cast<int32_t*>(state1_));
677*d9f75844SAndroid Build Coastguard Worker 
678*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < (lengthIn * 2); i += 220) {
679*d9f75844SAndroid Build Coastguard Worker         WebRtcSpl_Resample22khzTo16khz(
680*d9f75844SAndroid Build Coastguard Worker             tmp + i, samplesOut + (i / 220) * 160,
681*d9f75844SAndroid Build Coastguard Worker             static_cast<WebRtcSpl_State22khzTo16khz*>(state2_), tmp_mem);
682*d9f75844SAndroid Build Coastguard Worker       }
683*d9f75844SAndroid Build Coastguard Worker 
684*d9f75844SAndroid Build Coastguard Worker       outLen = (lengthIn * 16) / 11;
685*d9f75844SAndroid Build Coastguard Worker 
686*d9f75844SAndroid Build Coastguard Worker       free(tmp_mem);
687*d9f75844SAndroid Build Coastguard Worker       free(tmp);
688*d9f75844SAndroid Build Coastguard Worker       return 0;
689*d9f75844SAndroid Build Coastguard Worker 
690*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode11To32:
691*d9f75844SAndroid Build Coastguard Worker 
692*d9f75844SAndroid Build Coastguard Worker       // We can only handle blocks of 110 samples
693*d9f75844SAndroid Build Coastguard Worker       if ((lengthIn % 110) != 0) {
694*d9f75844SAndroid Build Coastguard Worker         return -1;
695*d9f75844SAndroid Build Coastguard Worker       }
696*d9f75844SAndroid Build Coastguard Worker       if (maxLen < ((lengthIn * 32) / 11)) {
697*d9f75844SAndroid Build Coastguard Worker         return -1;
698*d9f75844SAndroid Build Coastguard Worker       }
699*d9f75844SAndroid Build Coastguard Worker 
700*d9f75844SAndroid Build Coastguard Worker       tmp_mem = static_cast<int32_t*>(malloc(104 * sizeof(int32_t)));
701*d9f75844SAndroid Build Coastguard Worker       tmp = static_cast<int16_t*>(malloc((sizeof(int16_t) * lengthIn * 2)));
702*d9f75844SAndroid Build Coastguard Worker 
703*d9f75844SAndroid Build Coastguard Worker       // 11 -> 22 kHz in samplesOut
704*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut,
705*d9f75844SAndroid Build Coastguard Worker                             static_cast<int32_t*>(state1_));
706*d9f75844SAndroid Build Coastguard Worker 
707*d9f75844SAndroid Build Coastguard Worker       // 22 -> 16 in tmp
708*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < (lengthIn * 2); i += 220) {
709*d9f75844SAndroid Build Coastguard Worker         WebRtcSpl_Resample22khzTo16khz(
710*d9f75844SAndroid Build Coastguard Worker             samplesOut + i, tmp + (i / 220) * 160,
711*d9f75844SAndroid Build Coastguard Worker             static_cast<WebRtcSpl_State22khzTo16khz*>(state2_), tmp_mem);
712*d9f75844SAndroid Build Coastguard Worker       }
713*d9f75844SAndroid Build Coastguard Worker 
714*d9f75844SAndroid Build Coastguard Worker       // 16 -> 32 in samplesOut
715*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_UpsampleBy2(tmp, (lengthIn * 16) / 11, samplesOut,
716*d9f75844SAndroid Build Coastguard Worker                             static_cast<int32_t*>(state3_));
717*d9f75844SAndroid Build Coastguard Worker 
718*d9f75844SAndroid Build Coastguard Worker       outLen = (lengthIn * 32) / 11;
719*d9f75844SAndroid Build Coastguard Worker 
720*d9f75844SAndroid Build Coastguard Worker       free(tmp_mem);
721*d9f75844SAndroid Build Coastguard Worker       free(tmp);
722*d9f75844SAndroid Build Coastguard Worker       return 0;
723*d9f75844SAndroid Build Coastguard Worker 
724*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode2To1:
725*d9f75844SAndroid Build Coastguard Worker       if (maxLen < (lengthIn / 2)) {
726*d9f75844SAndroid Build Coastguard Worker         return -1;
727*d9f75844SAndroid Build Coastguard Worker       }
728*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, samplesOut,
729*d9f75844SAndroid Build Coastguard Worker                               static_cast<int32_t*>(state1_));
730*d9f75844SAndroid Build Coastguard Worker       outLen = lengthIn / 2;
731*d9f75844SAndroid Build Coastguard Worker       return 0;
732*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode3To1:
733*d9f75844SAndroid Build Coastguard Worker       // We can only handle blocks of 480 samples
734*d9f75844SAndroid Build Coastguard Worker       // Can be fixed, but I don't think it's needed
735*d9f75844SAndroid Build Coastguard Worker       if ((lengthIn % 480) != 0) {
736*d9f75844SAndroid Build Coastguard Worker         return -1;
737*d9f75844SAndroid Build Coastguard Worker       }
738*d9f75844SAndroid Build Coastguard Worker       if (maxLen < (lengthIn / 3)) {
739*d9f75844SAndroid Build Coastguard Worker         return -1;
740*d9f75844SAndroid Build Coastguard Worker       }
741*d9f75844SAndroid Build Coastguard Worker       tmp_mem = static_cast<int32_t*>(malloc(496 * sizeof(int32_t)));
742*d9f75844SAndroid Build Coastguard Worker 
743*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < lengthIn; i += 480) {
744*d9f75844SAndroid Build Coastguard Worker         WebRtcSpl_Resample48khzTo16khz(
745*d9f75844SAndroid Build Coastguard Worker             samplesIn + i, samplesOut + i / 3,
746*d9f75844SAndroid Build Coastguard Worker             static_cast<WebRtcSpl_State48khzTo16khz*>(state1_), tmp_mem);
747*d9f75844SAndroid Build Coastguard Worker       }
748*d9f75844SAndroid Build Coastguard Worker       outLen = lengthIn / 3;
749*d9f75844SAndroid Build Coastguard Worker       free(tmp_mem);
750*d9f75844SAndroid Build Coastguard Worker       return 0;
751*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode4To1:
752*d9f75844SAndroid Build Coastguard Worker       if (maxLen < (lengthIn / 4)) {
753*d9f75844SAndroid Build Coastguard Worker         return -1;
754*d9f75844SAndroid Build Coastguard Worker       }
755*d9f75844SAndroid Build Coastguard Worker       tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * lengthIn / 2));
756*d9f75844SAndroid Build Coastguard Worker       // 4:2
757*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, tmp,
758*d9f75844SAndroid Build Coastguard Worker                               static_cast<int32_t*>(state1_));
759*d9f75844SAndroid Build Coastguard Worker       // 2:1
760*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_DownsampleBy2(tmp, lengthIn / 2, samplesOut,
761*d9f75844SAndroid Build Coastguard Worker                               static_cast<int32_t*>(state2_));
762*d9f75844SAndroid Build Coastguard Worker       outLen = lengthIn / 4;
763*d9f75844SAndroid Build Coastguard Worker       free(tmp);
764*d9f75844SAndroid Build Coastguard Worker       return 0;
765*d9f75844SAndroid Build Coastguard Worker 
766*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode6To1:
767*d9f75844SAndroid Build Coastguard Worker       // We can only handle blocks of 480 samples
768*d9f75844SAndroid Build Coastguard Worker       // Can be fixed, but I don't think it's needed
769*d9f75844SAndroid Build Coastguard Worker       if ((lengthIn % 480) != 0) {
770*d9f75844SAndroid Build Coastguard Worker         return -1;
771*d9f75844SAndroid Build Coastguard Worker       }
772*d9f75844SAndroid Build Coastguard Worker       if (maxLen < (lengthIn / 6)) {
773*d9f75844SAndroid Build Coastguard Worker         return -1;
774*d9f75844SAndroid Build Coastguard Worker       }
775*d9f75844SAndroid Build Coastguard Worker 
776*d9f75844SAndroid Build Coastguard Worker       tmp_mem = static_cast<int32_t*>(malloc(496 * sizeof(int32_t)));
777*d9f75844SAndroid Build Coastguard Worker       tmp = static_cast<int16_t*>(malloc((sizeof(int16_t) * lengthIn) / 3));
778*d9f75844SAndroid Build Coastguard Worker 
779*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < lengthIn; i += 480) {
780*d9f75844SAndroid Build Coastguard Worker         WebRtcSpl_Resample48khzTo16khz(
781*d9f75844SAndroid Build Coastguard Worker             samplesIn + i, tmp + i / 3,
782*d9f75844SAndroid Build Coastguard Worker             static_cast<WebRtcSpl_State48khzTo16khz*>(state1_), tmp_mem);
783*d9f75844SAndroid Build Coastguard Worker       }
784*d9f75844SAndroid Build Coastguard Worker       outLen = lengthIn / 3;
785*d9f75844SAndroid Build Coastguard Worker       free(tmp_mem);
786*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_DownsampleBy2(tmp, outLen, samplesOut,
787*d9f75844SAndroid Build Coastguard Worker                               static_cast<int32_t*>(state2_));
788*d9f75844SAndroid Build Coastguard Worker       free(tmp);
789*d9f75844SAndroid Build Coastguard Worker       outLen = outLen / 2;
790*d9f75844SAndroid Build Coastguard Worker       return 0;
791*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode12To1:
792*d9f75844SAndroid Build Coastguard Worker       // We can only handle blocks of 480 samples
793*d9f75844SAndroid Build Coastguard Worker       // Can be fixed, but I don't think it's needed
794*d9f75844SAndroid Build Coastguard Worker       if ((lengthIn % 480) != 0) {
795*d9f75844SAndroid Build Coastguard Worker         return -1;
796*d9f75844SAndroid Build Coastguard Worker       }
797*d9f75844SAndroid Build Coastguard Worker       if (maxLen < (lengthIn / 12)) {
798*d9f75844SAndroid Build Coastguard Worker         return -1;
799*d9f75844SAndroid Build Coastguard Worker       }
800*d9f75844SAndroid Build Coastguard Worker 
801*d9f75844SAndroid Build Coastguard Worker       tmp_mem = static_cast<int32_t*>(malloc(496 * sizeof(int32_t)));
802*d9f75844SAndroid Build Coastguard Worker       tmp = static_cast<int16_t*>(malloc((sizeof(int16_t) * lengthIn) / 3));
803*d9f75844SAndroid Build Coastguard Worker       tmp_2 = static_cast<int16_t*>(malloc((sizeof(int16_t) * lengthIn) / 6));
804*d9f75844SAndroid Build Coastguard Worker       // 12:4
805*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < lengthIn; i += 480) {
806*d9f75844SAndroid Build Coastguard Worker         // WebRtcSpl_Resample48khzTo16khz() takes a block of 480 samples
807*d9f75844SAndroid Build Coastguard Worker         // as input and outputs a resampled block of 160 samples. The
808*d9f75844SAndroid Build Coastguard Worker         // data is now actually in 96 kHz sampling rate, despite the
809*d9f75844SAndroid Build Coastguard Worker         // function name, and with a resampling factor of 1/3 becomes
810*d9f75844SAndroid Build Coastguard Worker         // 32 kHz.
811*d9f75844SAndroid Build Coastguard Worker         WebRtcSpl_Resample48khzTo16khz(
812*d9f75844SAndroid Build Coastguard Worker             samplesIn + i, tmp + i / 3,
813*d9f75844SAndroid Build Coastguard Worker             static_cast<WebRtcSpl_State48khzTo16khz*>(state1_), tmp_mem);
814*d9f75844SAndroid Build Coastguard Worker       }
815*d9f75844SAndroid Build Coastguard Worker       outLen = lengthIn / 3;
816*d9f75844SAndroid Build Coastguard Worker       free(tmp_mem);
817*d9f75844SAndroid Build Coastguard Worker       // 4:2
818*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_DownsampleBy2(tmp, outLen, tmp_2,
819*d9f75844SAndroid Build Coastguard Worker                               static_cast<int32_t*>(state2_));
820*d9f75844SAndroid Build Coastguard Worker       outLen = outLen / 2;
821*d9f75844SAndroid Build Coastguard Worker       free(tmp);
822*d9f75844SAndroid Build Coastguard Worker       // 2:1
823*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_DownsampleBy2(tmp_2, outLen, samplesOut,
824*d9f75844SAndroid Build Coastguard Worker                               static_cast<int32_t*>(state3_));
825*d9f75844SAndroid Build Coastguard Worker       free(tmp_2);
826*d9f75844SAndroid Build Coastguard Worker       outLen = outLen / 2;
827*d9f75844SAndroid Build Coastguard Worker       return 0;
828*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode3To2:
829*d9f75844SAndroid Build Coastguard Worker       if (maxLen < (lengthIn * 2 / 3)) {
830*d9f75844SAndroid Build Coastguard Worker         return -1;
831*d9f75844SAndroid Build Coastguard Worker       }
832*d9f75844SAndroid Build Coastguard Worker       // 3:6
833*d9f75844SAndroid Build Coastguard Worker       tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * lengthIn * 2));
834*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp,
835*d9f75844SAndroid Build Coastguard Worker                             static_cast<int32_t*>(state1_));
836*d9f75844SAndroid Build Coastguard Worker       lengthIn *= 2;
837*d9f75844SAndroid Build Coastguard Worker       // 6:2
838*d9f75844SAndroid Build Coastguard Worker       // We can only handle blocks of 480 samples
839*d9f75844SAndroid Build Coastguard Worker       // Can be fixed, but I don't think it's needed
840*d9f75844SAndroid Build Coastguard Worker       if ((lengthIn % 480) != 0) {
841*d9f75844SAndroid Build Coastguard Worker         free(tmp);
842*d9f75844SAndroid Build Coastguard Worker         return -1;
843*d9f75844SAndroid Build Coastguard Worker       }
844*d9f75844SAndroid Build Coastguard Worker       tmp_mem = static_cast<int32_t*>(malloc(496 * sizeof(int32_t)));
845*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < lengthIn; i += 480) {
846*d9f75844SAndroid Build Coastguard Worker         WebRtcSpl_Resample48khzTo16khz(
847*d9f75844SAndroid Build Coastguard Worker             tmp + i, samplesOut + i / 3,
848*d9f75844SAndroid Build Coastguard Worker             static_cast<WebRtcSpl_State48khzTo16khz*>(state2_), tmp_mem);
849*d9f75844SAndroid Build Coastguard Worker       }
850*d9f75844SAndroid Build Coastguard Worker       outLen = lengthIn / 3;
851*d9f75844SAndroid Build Coastguard Worker       free(tmp);
852*d9f75844SAndroid Build Coastguard Worker       free(tmp_mem);
853*d9f75844SAndroid Build Coastguard Worker       return 0;
854*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode11To2:
855*d9f75844SAndroid Build Coastguard Worker       // We can only handle blocks of 220 samples
856*d9f75844SAndroid Build Coastguard Worker       // Can be fixed, but I don't think it's needed
857*d9f75844SAndroid Build Coastguard Worker       if ((lengthIn % 220) != 0) {
858*d9f75844SAndroid Build Coastguard Worker         return -1;
859*d9f75844SAndroid Build Coastguard Worker       }
860*d9f75844SAndroid Build Coastguard Worker       if (maxLen < ((lengthIn * 2) / 11)) {
861*d9f75844SAndroid Build Coastguard Worker         return -1;
862*d9f75844SAndroid Build Coastguard Worker       }
863*d9f75844SAndroid Build Coastguard Worker       tmp_mem = static_cast<int32_t*>(malloc(126 * sizeof(int32_t)));
864*d9f75844SAndroid Build Coastguard Worker       tmp =
865*d9f75844SAndroid Build Coastguard Worker           static_cast<int16_t*>(malloc((lengthIn * 4) / 11 * sizeof(int16_t)));
866*d9f75844SAndroid Build Coastguard Worker 
867*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < lengthIn; i += 220) {
868*d9f75844SAndroid Build Coastguard Worker         WebRtcSpl_Resample22khzTo8khz(
869*d9f75844SAndroid Build Coastguard Worker             samplesIn + i, tmp + (i * 4) / 11,
870*d9f75844SAndroid Build Coastguard Worker             static_cast<WebRtcSpl_State22khzTo8khz*>(state1_), tmp_mem);
871*d9f75844SAndroid Build Coastguard Worker       }
872*d9f75844SAndroid Build Coastguard Worker       lengthIn = (lengthIn * 4) / 11;
873*d9f75844SAndroid Build Coastguard Worker 
874*d9f75844SAndroid Build Coastguard Worker       WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut,
875*d9f75844SAndroid Build Coastguard Worker                               static_cast<int32_t*>(state2_));
876*d9f75844SAndroid Build Coastguard Worker       outLen = lengthIn / 2;
877*d9f75844SAndroid Build Coastguard Worker 
878*d9f75844SAndroid Build Coastguard Worker       free(tmp_mem);
879*d9f75844SAndroid Build Coastguard Worker       free(tmp);
880*d9f75844SAndroid Build Coastguard Worker       return 0;
881*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode11To4:
882*d9f75844SAndroid Build Coastguard Worker       // We can only handle blocks of 220 samples
883*d9f75844SAndroid Build Coastguard Worker       // Can be fixed, but I don't think it's needed
884*d9f75844SAndroid Build Coastguard Worker       if ((lengthIn % 220) != 0) {
885*d9f75844SAndroid Build Coastguard Worker         return -1;
886*d9f75844SAndroid Build Coastguard Worker       }
887*d9f75844SAndroid Build Coastguard Worker       if (maxLen < ((lengthIn * 4) / 11)) {
888*d9f75844SAndroid Build Coastguard Worker         return -1;
889*d9f75844SAndroid Build Coastguard Worker       }
890*d9f75844SAndroid Build Coastguard Worker       tmp_mem = static_cast<int32_t*>(malloc(126 * sizeof(int32_t)));
891*d9f75844SAndroid Build Coastguard Worker 
892*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < lengthIn; i += 220) {
893*d9f75844SAndroid Build Coastguard Worker         WebRtcSpl_Resample22khzTo8khz(
894*d9f75844SAndroid Build Coastguard Worker             samplesIn + i, samplesOut + (i * 4) / 11,
895*d9f75844SAndroid Build Coastguard Worker             static_cast<WebRtcSpl_State22khzTo8khz*>(state1_), tmp_mem);
896*d9f75844SAndroid Build Coastguard Worker       }
897*d9f75844SAndroid Build Coastguard Worker       outLen = (lengthIn * 4) / 11;
898*d9f75844SAndroid Build Coastguard Worker       free(tmp_mem);
899*d9f75844SAndroid Build Coastguard Worker       return 0;
900*d9f75844SAndroid Build Coastguard Worker     case kResamplerMode11To8:
901*d9f75844SAndroid Build Coastguard Worker       // We can only handle blocks of 160 samples
902*d9f75844SAndroid Build Coastguard Worker       // Can be fixed, but I don't think it's needed
903*d9f75844SAndroid Build Coastguard Worker       if ((lengthIn % 220) != 0) {
904*d9f75844SAndroid Build Coastguard Worker         return -1;
905*d9f75844SAndroid Build Coastguard Worker       }
906*d9f75844SAndroid Build Coastguard Worker       if (maxLen < ((lengthIn * 8) / 11)) {
907*d9f75844SAndroid Build Coastguard Worker         return -1;
908*d9f75844SAndroid Build Coastguard Worker       }
909*d9f75844SAndroid Build Coastguard Worker       tmp_mem = static_cast<int32_t*>(malloc(104 * sizeof(int32_t)));
910*d9f75844SAndroid Build Coastguard Worker 
911*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < lengthIn; i += 220) {
912*d9f75844SAndroid Build Coastguard Worker         WebRtcSpl_Resample22khzTo16khz(
913*d9f75844SAndroid Build Coastguard Worker             samplesIn + i, samplesOut + (i * 8) / 11,
914*d9f75844SAndroid Build Coastguard Worker             static_cast<WebRtcSpl_State22khzTo16khz*>(state1_), tmp_mem);
915*d9f75844SAndroid Build Coastguard Worker       }
916*d9f75844SAndroid Build Coastguard Worker       outLen = (lengthIn * 8) / 11;
917*d9f75844SAndroid Build Coastguard Worker       free(tmp_mem);
918*d9f75844SAndroid Build Coastguard Worker       return 0;
919*d9f75844SAndroid Build Coastguard Worker   }
920*d9f75844SAndroid Build Coastguard Worker   return 0;
921*d9f75844SAndroid Build Coastguard Worker }
922*d9f75844SAndroid Build Coastguard Worker 
923*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
924