blob: 7c690fc47a2bd553afa229c8f2eb426011f699ee [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11
12/*
13 * A wrapper for resampling a numerous amount of sampling combinations.
14 */
15
16#include <stdlib.h>
17#include <string.h>
18
pbos@webrtc.orgaa30bb72013-05-27 09:49:58 +000019#include "webrtc/common_audio/resampler/include/resampler.h"
20#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000021
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -070022namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000023
24Resampler::Resampler()
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -070025 : state1_(nullptr),
26 state2_(nullptr),
27 state3_(nullptr),
28 in_buffer_(nullptr),
29 out_buffer_(nullptr),
30 in_buffer_size_(0),
31 out_buffer_size_(0),
32 in_buffer_size_max_(0),
33 out_buffer_size_max_(0),
34 my_in_frequency_khz_(0),
35 my_out_frequency_khz_(0),
36 my_mode_(kResamplerMode1To1),
37 num_channels_(0),
38 slave_left_(nullptr),
39 slave_right_(nullptr) {
niklase@google.com470e71d2011-07-07 08:21:25 +000040}
41
Peter Kasting69558702016-01-12 16:26:35 -080042Resampler::Resampler(int inFreq, int outFreq, size_t num_channels)
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -070043 : Resampler() {
44 Reset(inFreq, outFreq, num_channels);
niklase@google.com470e71d2011-07-07 08:21:25 +000045}
46
47Resampler::~Resampler()
48{
49 if (state1_)
50 {
51 free(state1_);
52 }
53 if (state2_)
54 {
55 free(state2_);
56 }
57 if (state3_)
58 {
59 free(state3_);
60 }
61 if (in_buffer_)
62 {
63 free(in_buffer_);
64 }
65 if (out_buffer_)
66 {
67 free(out_buffer_);
68 }
69 if (slave_left_)
70 {
71 delete slave_left_;
72 }
73 if (slave_right_)
74 {
75 delete slave_right_;
76 }
77}
78
Peter Kasting69558702016-01-12 16:26:35 -080079int Resampler::ResetIfNeeded(int inFreq, int outFreq, size_t num_channels)
niklase@google.com470e71d2011-07-07 08:21:25 +000080{
81 int tmpInFreq_kHz = inFreq / 1000;
82 int tmpOutFreq_kHz = outFreq / 1000;
83
84 if ((tmpInFreq_kHz != my_in_frequency_khz_) || (tmpOutFreq_kHz != my_out_frequency_khz_)
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -070085 || (num_channels != num_channels_))
niklase@google.com470e71d2011-07-07 08:21:25 +000086 {
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -070087 return Reset(inFreq, outFreq, num_channels);
niklase@google.com470e71d2011-07-07 08:21:25 +000088 } else
89 {
90 return 0;
91 }
92}
93
Peter Kasting69558702016-01-12 16:26:35 -080094int Resampler::Reset(int inFreq, int outFreq, size_t num_channels)
niklase@google.com470e71d2011-07-07 08:21:25 +000095{
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -070096 if (num_channels != 1 && num_channels != 2) {
97 return -1;
98 }
99 num_channels_ = num_channels;
niklase@google.com470e71d2011-07-07 08:21:25 +0000100
101 if (state1_)
102 {
103 free(state1_);
104 state1_ = NULL;
105 }
106 if (state2_)
107 {
108 free(state2_);
109 state2_ = NULL;
110 }
111 if (state3_)
112 {
113 free(state3_);
114 state3_ = NULL;
115 }
116 if (in_buffer_)
117 {
118 free(in_buffer_);
119 in_buffer_ = NULL;
120 }
121 if (out_buffer_)
122 {
123 free(out_buffer_);
124 out_buffer_ = NULL;
125 }
126 if (slave_left_)
127 {
128 delete slave_left_;
129 slave_left_ = NULL;
130 }
131 if (slave_right_)
132 {
133 delete slave_right_;
134 slave_right_ = NULL;
135 }
136
137 in_buffer_size_ = 0;
138 out_buffer_size_ = 0;
139 in_buffer_size_max_ = 0;
140 out_buffer_size_max_ = 0;
141
niklase@google.com470e71d2011-07-07 08:21:25 +0000142 // Start with a math exercise, Euclid's algorithm to find the gcd:
niklase@google.com470e71d2011-07-07 08:21:25 +0000143 int a = inFreq;
144 int b = outFreq;
145 int c = a % b;
146 while (c != 0)
147 {
148 a = b;
149 b = c;
150 c = a % b;
151 }
152 // b is now the gcd;
153
154 // We need to track what domain we're in.
155 my_in_frequency_khz_ = inFreq / 1000;
156 my_out_frequency_khz_ = outFreq / 1000;
157
158 // Scale with GCD
159 inFreq = inFreq / b;
160 outFreq = outFreq / b;
161
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -0700162 if (num_channels_ == 2)
niklase@google.com470e71d2011-07-07 08:21:25 +0000163 {
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -0700164 // Create two mono resamplers.
165 slave_left_ = new Resampler(inFreq, outFreq, 1);
166 slave_right_ = new Resampler(inFreq, outFreq, 1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000167 }
168
169 if (inFreq == outFreq)
170 {
171 my_mode_ = kResamplerMode1To1;
172 } else if (inFreq == 1)
173 {
174 switch (outFreq)
175 {
176 case 2:
177 my_mode_ = kResamplerMode1To2;
178 break;
179 case 3:
180 my_mode_ = kResamplerMode1To3;
181 break;
182 case 4:
183 my_mode_ = kResamplerMode1To4;
184 break;
185 case 6:
186 my_mode_ = kResamplerMode1To6;
187 break;
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000188 case 12:
189 my_mode_ = kResamplerMode1To12;
190 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000191 default:
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +0000192 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000193 }
194 } else if (outFreq == 1)
195 {
196 switch (inFreq)
197 {
198 case 2:
199 my_mode_ = kResamplerMode2To1;
200 break;
201 case 3:
202 my_mode_ = kResamplerMode3To1;
203 break;
204 case 4:
205 my_mode_ = kResamplerMode4To1;
206 break;
207 case 6:
208 my_mode_ = kResamplerMode6To1;
209 break;
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000210 case 12:
211 my_mode_ = kResamplerMode12To1;
212 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000213 default:
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +0000214 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000215 }
216 } else if ((inFreq == 2) && (outFreq == 3))
217 {
218 my_mode_ = kResamplerMode2To3;
219 } else if ((inFreq == 2) && (outFreq == 11))
220 {
221 my_mode_ = kResamplerMode2To11;
222 } else if ((inFreq == 4) && (outFreq == 11))
223 {
224 my_mode_ = kResamplerMode4To11;
225 } else if ((inFreq == 8) && (outFreq == 11))
226 {
227 my_mode_ = kResamplerMode8To11;
228 } else if ((inFreq == 3) && (outFreq == 2))
229 {
230 my_mode_ = kResamplerMode3To2;
231 } else if ((inFreq == 11) && (outFreq == 2))
232 {
233 my_mode_ = kResamplerMode11To2;
234 } else if ((inFreq == 11) && (outFreq == 4))
235 {
236 my_mode_ = kResamplerMode11To4;
237 } else if ((inFreq == 11) && (outFreq == 16))
238 {
239 my_mode_ = kResamplerMode11To16;
240 } else if ((inFreq == 11) && (outFreq == 32))
241 {
242 my_mode_ = kResamplerMode11To32;
243 } else if ((inFreq == 11) && (outFreq == 8))
244 {
245 my_mode_ = kResamplerMode11To8;
246 } else
247 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000248 return -1;
249 }
250
251 // Now create the states we need
252 switch (my_mode_)
253 {
254 case kResamplerMode1To1:
255 // No state needed;
256 break;
257 case kResamplerMode1To2:
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000258 state1_ = malloc(8 * sizeof(int32_t));
259 memset(state1_, 0, 8 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000260 break;
261 case kResamplerMode1To3:
262 state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
263 WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state1_);
264 break;
265 case kResamplerMode1To4:
266 // 1:2
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000267 state1_ = malloc(8 * sizeof(int32_t));
268 memset(state1_, 0, 8 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000269 // 2:4
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000270 state2_ = malloc(8 * sizeof(int32_t));
271 memset(state2_, 0, 8 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000272 break;
273 case kResamplerMode1To6:
274 // 1:2
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000275 state1_ = malloc(8 * sizeof(int32_t));
276 memset(state1_, 0, 8 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000277 // 2:6
278 state2_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
279 WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state2_);
280 break;
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000281 case kResamplerMode1To12:
282 // 1:2
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000283 state1_ = malloc(8 * sizeof(int32_t));
284 memset(state1_, 0, 8 * sizeof(int32_t));
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000285 // 2:4
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000286 state2_ = malloc(8 * sizeof(int32_t));
287 memset(state2_, 0, 8 * sizeof(int32_t));
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000288 // 4:12
289 state3_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
290 WebRtcSpl_ResetResample16khzTo48khz(
291 (WebRtcSpl_State16khzTo48khz*) state3_);
292 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000293 case kResamplerMode2To3:
294 // 2:6
295 state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
296 WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state1_);
297 // 6:3
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000298 state2_ = malloc(8 * sizeof(int32_t));
299 memset(state2_, 0, 8 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000300 break;
301 case kResamplerMode2To11:
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000302 state1_ = malloc(8 * sizeof(int32_t));
303 memset(state1_, 0, 8 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000304
305 state2_ = malloc(sizeof(WebRtcSpl_State8khzTo22khz));
306 WebRtcSpl_ResetResample8khzTo22khz((WebRtcSpl_State8khzTo22khz *)state2_);
307 break;
308 case kResamplerMode4To11:
309 state1_ = malloc(sizeof(WebRtcSpl_State8khzTo22khz));
310 WebRtcSpl_ResetResample8khzTo22khz((WebRtcSpl_State8khzTo22khz *)state1_);
311 break;
312 case kResamplerMode8To11:
313 state1_ = malloc(sizeof(WebRtcSpl_State16khzTo22khz));
314 WebRtcSpl_ResetResample16khzTo22khz((WebRtcSpl_State16khzTo22khz *)state1_);
315 break;
316 case kResamplerMode11To16:
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000317 state1_ = malloc(8 * sizeof(int32_t));
318 memset(state1_, 0, 8 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000319
320 state2_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz));
321 WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state2_);
322 break;
323 case kResamplerMode11To32:
324 // 11 -> 22
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000325 state1_ = malloc(8 * sizeof(int32_t));
326 memset(state1_, 0, 8 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000327
328 // 22 -> 16
329 state2_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz));
330 WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state2_);
331
332 // 16 -> 32
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000333 state3_ = malloc(8 * sizeof(int32_t));
334 memset(state3_, 0, 8 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000335
336 break;
337 case kResamplerMode2To1:
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000338 state1_ = malloc(8 * sizeof(int32_t));
339 memset(state1_, 0, 8 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000340 break;
341 case kResamplerMode3To1:
342 state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
343 WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state1_);
344 break;
345 case kResamplerMode4To1:
346 // 4:2
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000347 state1_ = malloc(8 * sizeof(int32_t));
348 memset(state1_, 0, 8 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000349 // 2:1
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000350 state2_ = malloc(8 * sizeof(int32_t));
351 memset(state2_, 0, 8 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000352 break;
353 case kResamplerMode6To1:
354 // 6:2
355 state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
356 WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state1_);
357 // 2:1
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000358 state2_ = malloc(8 * sizeof(int32_t));
359 memset(state2_, 0, 8 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000360 break;
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000361 case kResamplerMode12To1:
362 // 12:4
363 state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
364 WebRtcSpl_ResetResample48khzTo16khz(
365 (WebRtcSpl_State48khzTo16khz*) state1_);
366 // 4:2
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000367 state2_ = malloc(8 * sizeof(int32_t));
368 memset(state2_, 0, 8 * sizeof(int32_t));
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000369 // 2:1
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000370 state3_ = malloc(8 * sizeof(int32_t));
371 memset(state3_, 0, 8 * sizeof(int32_t));
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000372 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000373 case kResamplerMode3To2:
374 // 3:6
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000375 state1_ = malloc(8 * sizeof(int32_t));
376 memset(state1_, 0, 8 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000377 // 6:2
378 state2_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
379 WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state2_);
380 break;
381 case kResamplerMode11To2:
382 state1_ = malloc(sizeof(WebRtcSpl_State22khzTo8khz));
383 WebRtcSpl_ResetResample22khzTo8khz((WebRtcSpl_State22khzTo8khz *)state1_);
384
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000385 state2_ = malloc(8 * sizeof(int32_t));
386 memset(state2_, 0, 8 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000387
388 break;
389 case kResamplerMode11To4:
390 state1_ = malloc(sizeof(WebRtcSpl_State22khzTo8khz));
391 WebRtcSpl_ResetResample22khzTo8khz((WebRtcSpl_State22khzTo8khz *)state1_);
392 break;
393 case kResamplerMode11To8:
394 state1_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz));
395 WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state1_);
396 break;
397
398 }
399
400 return 0;
401}
402
403// Synchronous resampling, all output samples are written to samplesOut
Peter Kastingdce40cf2015-08-24 14:52:23 -0700404int Resampler::Push(const int16_t * samplesIn, size_t lengthIn,
405 int16_t* samplesOut, size_t maxLen, size_t &outLen)
niklase@google.com470e71d2011-07-07 08:21:25 +0000406{
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -0700407 if (num_channels_ == 2)
niklase@google.com470e71d2011-07-07 08:21:25 +0000408 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000409 // Split up the signal and call the slave object for each channel
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000410 int16_t* left = (int16_t*)malloc(lengthIn * sizeof(int16_t) / 2);
411 int16_t* right = (int16_t*)malloc(lengthIn * sizeof(int16_t) / 2);
412 int16_t* out_left = (int16_t*)malloc(maxLen / 2 * sizeof(int16_t));
413 int16_t* out_right =
414 (int16_t*)malloc(maxLen / 2 * sizeof(int16_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000415 int res = 0;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700416 for (size_t i = 0; i < lengthIn; i += 2)
niklase@google.com470e71d2011-07-07 08:21:25 +0000417 {
418 left[i >> 1] = samplesIn[i];
419 right[i >> 1] = samplesIn[i + 1];
420 }
421
422 // It's OK to overwrite the local parameter, since it's just a copy
423 lengthIn = lengthIn / 2;
424
Peter Kastingdce40cf2015-08-24 14:52:23 -0700425 size_t actualOutLen_left = 0;
426 size_t actualOutLen_right = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000427 // Do resampling for right channel
428 res |= slave_left_->Push(left, lengthIn, out_left, maxLen / 2, actualOutLen_left);
429 res |= slave_right_->Push(right, lengthIn, out_right, maxLen / 2, actualOutLen_right);
430 if (res || (actualOutLen_left != actualOutLen_right))
431 {
432 free(left);
433 free(right);
434 free(out_left);
435 free(out_right);
436 return -1;
437 }
438
439 // Reassemble the signal
Peter Kastingdce40cf2015-08-24 14:52:23 -0700440 for (size_t i = 0; i < actualOutLen_left; i++)
niklase@google.com470e71d2011-07-07 08:21:25 +0000441 {
442 samplesOut[i * 2] = out_left[i];
443 samplesOut[i * 2 + 1] = out_right[i];
444 }
445 outLen = 2 * actualOutLen_left;
446
447 free(left);
448 free(right);
449 free(out_left);
450 free(out_right);
451
452 return 0;
453 }
454
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000455 // Containers for temp samples
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000456 int16_t* tmp;
457 int16_t* tmp_2;
niklase@google.com470e71d2011-07-07 08:21:25 +0000458 // tmp data for resampling routines
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000459 int32_t* tmp_mem;
niklase@google.com470e71d2011-07-07 08:21:25 +0000460
461 switch (my_mode_)
462 {
463 case kResamplerMode1To1:
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000464 memcpy(samplesOut, samplesIn, lengthIn * sizeof(int16_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000465 outLen = lengthIn;
466 break;
467 case kResamplerMode1To2:
468 if (maxLen < (lengthIn * 2))
469 {
470 return -1;
471 }
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000472 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, (int32_t*)state1_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000473 outLen = lengthIn * 2;
474 return 0;
475 case kResamplerMode1To3:
476
477 // We can only handle blocks of 160 samples
478 // Can be fixed, but I don't think it's needed
479 if ((lengthIn % 160) != 0)
480 {
481 return -1;
482 }
483 if (maxLen < (lengthIn * 3))
484 {
485 return -1;
486 }
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000487 tmp_mem = (int32_t*)malloc(336 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000488
Peter Kastingdce40cf2015-08-24 14:52:23 -0700489 for (size_t i = 0; i < lengthIn; i += 160)
niklase@google.com470e71d2011-07-07 08:21:25 +0000490 {
491 WebRtcSpl_Resample16khzTo48khz(samplesIn + i, samplesOut + i * 3,
492 (WebRtcSpl_State16khzTo48khz *)state1_,
493 tmp_mem);
494 }
495 outLen = lengthIn * 3;
496 free(tmp_mem);
497 return 0;
498 case kResamplerMode1To4:
499 if (maxLen < (lengthIn * 4))
500 {
501 return -1;
502 }
503
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000504 tmp = (int16_t*)malloc(sizeof(int16_t) * 2 * lengthIn);
niklase@google.com470e71d2011-07-07 08:21:25 +0000505 // 1:2
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000506 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (int32_t*)state1_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000507 // 2:4
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000508 WebRtcSpl_UpsampleBy2(tmp, lengthIn * 2, samplesOut, (int32_t*)state2_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000509 outLen = lengthIn * 4;
510 free(tmp);
511 return 0;
512 case kResamplerMode1To6:
513 // We can only handle blocks of 80 samples
514 // Can be fixed, but I don't think it's needed
515 if ((lengthIn % 80) != 0)
516 {
517 return -1;
518 }
519 if (maxLen < (lengthIn * 6))
520 {
521 return -1;
522 }
523
524 //1:2
525
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000526 tmp_mem = (int32_t*)malloc(336 * sizeof(int32_t));
527 tmp = (int16_t*)malloc(sizeof(int16_t) * 2 * lengthIn);
niklase@google.com470e71d2011-07-07 08:21:25 +0000528
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000529 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (int32_t*)state1_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000530 outLen = lengthIn * 2;
531
Peter Kastingdce40cf2015-08-24 14:52:23 -0700532 for (size_t i = 0; i < outLen; i += 160)
niklase@google.com470e71d2011-07-07 08:21:25 +0000533 {
534 WebRtcSpl_Resample16khzTo48khz(tmp + i, samplesOut + i * 3,
535 (WebRtcSpl_State16khzTo48khz *)state2_,
536 tmp_mem);
537 }
538 outLen = outLen * 3;
539 free(tmp_mem);
540 free(tmp);
541
542 return 0;
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000543 case kResamplerMode1To12:
544 // We can only handle blocks of 40 samples
545 // Can be fixed, but I don't think it's needed
546 if ((lengthIn % 40) != 0) {
547 return -1;
548 }
549 if (maxLen < (lengthIn * 12)) {
550 return -1;
551 }
552
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000553 tmp_mem = (int32_t*) malloc(336 * sizeof(int32_t));
554 tmp = (int16_t*) malloc(sizeof(int16_t) * 4 * lengthIn);
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000555 //1:2
556 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut,
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000557 (int32_t*) state1_);
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000558 outLen = lengthIn * 2;
559 //2:4
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000560 WebRtcSpl_UpsampleBy2(samplesOut, outLen, tmp, (int32_t*) state2_);
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000561 outLen = outLen * 2;
562 // 4:12
Peter Kastingdce40cf2015-08-24 14:52:23 -0700563 for (size_t i = 0; i < outLen; i += 160) {
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000564 // WebRtcSpl_Resample16khzTo48khz() takes a block of 160 samples
565 // as input and outputs a resampled block of 480 samples. The
566 // data is now actually in 32 kHz sampling rate, despite the
567 // function name, and with a resampling factor of three becomes
568 // 96 kHz.
569 WebRtcSpl_Resample16khzTo48khz(tmp + i, samplesOut + i * 3,
570 (WebRtcSpl_State16khzTo48khz*) state3_,
571 tmp_mem);
572 }
573 outLen = outLen * 3;
574 free(tmp_mem);
575 free(tmp);
576
577 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000578 case kResamplerMode2To3:
579 if (maxLen < (lengthIn * 3 / 2))
580 {
581 return -1;
582 }
583 // 2:6
584 // We can only handle blocks of 160 samples
585 // Can be fixed, but I don't think it's needed
586 if ((lengthIn % 160) != 0)
587 {
588 return -1;
589 }
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000590 tmp = static_cast<int16_t*> (malloc(sizeof(int16_t) * lengthIn * 3));
591 tmp_mem = (int32_t*)malloc(336 * sizeof(int32_t));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700592 for (size_t i = 0; i < lengthIn; i += 160)
niklase@google.com470e71d2011-07-07 08:21:25 +0000593 {
594 WebRtcSpl_Resample16khzTo48khz(samplesIn + i, tmp + i * 3,
595 (WebRtcSpl_State16khzTo48khz *)state1_,
596 tmp_mem);
597 }
598 lengthIn = lengthIn * 3;
599 // 6:3
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000600 WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut, (int32_t*)state2_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000601 outLen = lengthIn / 2;
602 free(tmp);
603 free(tmp_mem);
604 return 0;
605 case kResamplerMode2To11:
606
607 // We can only handle blocks of 80 samples
608 // Can be fixed, but I don't think it's needed
609 if ((lengthIn % 80) != 0)
610 {
611 return -1;
612 }
613 if (maxLen < ((lengthIn * 11) / 2))
614 {
615 return -1;
616 }
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000617 tmp = (int16_t*)malloc(sizeof(int16_t) * 2 * lengthIn);
niklase@google.com470e71d2011-07-07 08:21:25 +0000618 // 1:2
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000619 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (int32_t*)state1_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000620 lengthIn *= 2;
621
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000622 tmp_mem = (int32_t*)malloc(98 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000623
Peter Kastingdce40cf2015-08-24 14:52:23 -0700624 for (size_t i = 0; i < lengthIn; i += 80)
niklase@google.com470e71d2011-07-07 08:21:25 +0000625 {
626 WebRtcSpl_Resample8khzTo22khz(tmp + i, samplesOut + (i * 11) / 4,
627 (WebRtcSpl_State8khzTo22khz *)state2_,
628 tmp_mem);
629 }
630 outLen = (lengthIn * 11) / 4;
631 free(tmp_mem);
632 free(tmp);
633 return 0;
634 case kResamplerMode4To11:
635
636 // We can only handle blocks of 80 samples
637 // Can be fixed, but I don't think it's needed
638 if ((lengthIn % 80) != 0)
639 {
640 return -1;
641 }
642 if (maxLen < ((lengthIn * 11) / 4))
643 {
644 return -1;
645 }
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000646 tmp_mem = (int32_t*)malloc(98 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000647
Peter Kastingdce40cf2015-08-24 14:52:23 -0700648 for (size_t i = 0; i < lengthIn; i += 80)
niklase@google.com470e71d2011-07-07 08:21:25 +0000649 {
650 WebRtcSpl_Resample8khzTo22khz(samplesIn + i, samplesOut + (i * 11) / 4,
651 (WebRtcSpl_State8khzTo22khz *)state1_,
652 tmp_mem);
653 }
654 outLen = (lengthIn * 11) / 4;
655 free(tmp_mem);
656 return 0;
657 case kResamplerMode8To11:
658 // We can only handle blocks of 160 samples
659 // Can be fixed, but I don't think it's needed
660 if ((lengthIn % 160) != 0)
661 {
662 return -1;
663 }
664 if (maxLen < ((lengthIn * 11) / 8))
665 {
666 return -1;
667 }
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000668 tmp_mem = (int32_t*)malloc(88 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000669
Peter Kastingdce40cf2015-08-24 14:52:23 -0700670 for (size_t i = 0; i < lengthIn; i += 160)
niklase@google.com470e71d2011-07-07 08:21:25 +0000671 {
672 WebRtcSpl_Resample16khzTo22khz(samplesIn + i, samplesOut + (i * 11) / 8,
673 (WebRtcSpl_State16khzTo22khz *)state1_,
674 tmp_mem);
675 }
676 outLen = (lengthIn * 11) / 8;
677 free(tmp_mem);
678 return 0;
679
680 case kResamplerMode11To16:
681 // We can only handle blocks of 110 samples
682 if ((lengthIn % 110) != 0)
683 {
684 return -1;
685 }
686 if (maxLen < ((lengthIn * 16) / 11))
687 {
688 return -1;
689 }
690
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000691 tmp_mem = (int32_t*)malloc(104 * sizeof(int32_t));
692 tmp = (int16_t*)malloc((sizeof(int16_t) * lengthIn * 2));
niklase@google.com470e71d2011-07-07 08:21:25 +0000693
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000694 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (int32_t*)state1_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000695
Peter Kastingdce40cf2015-08-24 14:52:23 -0700696 for (size_t i = 0; i < (lengthIn * 2); i += 220)
niklase@google.com470e71d2011-07-07 08:21:25 +0000697 {
698 WebRtcSpl_Resample22khzTo16khz(tmp + i, samplesOut + (i / 220) * 160,
699 (WebRtcSpl_State22khzTo16khz *)state2_,
700 tmp_mem);
701 }
702
703 outLen = (lengthIn * 16) / 11;
704
705 free(tmp_mem);
706 free(tmp);
707 return 0;
708
709 case kResamplerMode11To32:
710
711 // We can only handle blocks of 110 samples
712 if ((lengthIn % 110) != 0)
713 {
714 return -1;
715 }
716 if (maxLen < ((lengthIn * 32) / 11))
717 {
718 return -1;
719 }
720
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000721 tmp_mem = (int32_t*)malloc(104 * sizeof(int32_t));
722 tmp = (int16_t*)malloc((sizeof(int16_t) * lengthIn * 2));
niklase@google.com470e71d2011-07-07 08:21:25 +0000723
724 // 11 -> 22 kHz in samplesOut
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000725 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, (int32_t*)state1_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000726
727 // 22 -> 16 in tmp
Peter Kastingdce40cf2015-08-24 14:52:23 -0700728 for (size_t i = 0; i < (lengthIn * 2); i += 220)
niklase@google.com470e71d2011-07-07 08:21:25 +0000729 {
730 WebRtcSpl_Resample22khzTo16khz(samplesOut + i, tmp + (i / 220) * 160,
731 (WebRtcSpl_State22khzTo16khz *)state2_,
732 tmp_mem);
733 }
734
735 // 16 -> 32 in samplesOut
736 WebRtcSpl_UpsampleBy2(tmp, (lengthIn * 16) / 11, samplesOut,
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000737 (int32_t*)state3_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000738
739 outLen = (lengthIn * 32) / 11;
740
741 free(tmp_mem);
742 free(tmp);
743 return 0;
744
745 case kResamplerMode2To1:
746 if (maxLen < (lengthIn / 2))
747 {
748 return -1;
749 }
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000750 WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, samplesOut, (int32_t*)state1_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000751 outLen = lengthIn / 2;
752 return 0;
753 case kResamplerMode3To1:
754 // We can only handle blocks of 480 samples
755 // Can be fixed, but I don't think it's needed
756 if ((lengthIn % 480) != 0)
757 {
758 return -1;
759 }
760 if (maxLen < (lengthIn / 3))
761 {
762 return -1;
763 }
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000764 tmp_mem = (int32_t*)malloc(496 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000765
Peter Kastingdce40cf2015-08-24 14:52:23 -0700766 for (size_t i = 0; i < lengthIn; i += 480)
niklase@google.com470e71d2011-07-07 08:21:25 +0000767 {
768 WebRtcSpl_Resample48khzTo16khz(samplesIn + i, samplesOut + i / 3,
769 (WebRtcSpl_State48khzTo16khz *)state1_,
770 tmp_mem);
771 }
772 outLen = lengthIn / 3;
773 free(tmp_mem);
774 return 0;
775 case kResamplerMode4To1:
776 if (maxLen < (lengthIn / 4))
777 {
778 return -1;
779 }
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000780 tmp = (int16_t*)malloc(sizeof(int16_t) * lengthIn / 2);
niklase@google.com470e71d2011-07-07 08:21:25 +0000781 // 4:2
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000782 WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, tmp, (int32_t*)state1_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000783 // 2:1
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000784 WebRtcSpl_DownsampleBy2(tmp, lengthIn / 2, samplesOut, (int32_t*)state2_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000785 outLen = lengthIn / 4;
786 free(tmp);
787 return 0;
788
789 case kResamplerMode6To1:
790 // We can only handle blocks of 480 samples
791 // Can be fixed, but I don't think it's needed
792 if ((lengthIn % 480) != 0)
793 {
794 return -1;
795 }
796 if (maxLen < (lengthIn / 6))
797 {
798 return -1;
799 }
800
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000801 tmp_mem = (int32_t*)malloc(496 * sizeof(int32_t));
802 tmp = (int16_t*)malloc((sizeof(int16_t) * lengthIn) / 3);
niklase@google.com470e71d2011-07-07 08:21:25 +0000803
Peter Kastingdce40cf2015-08-24 14:52:23 -0700804 for (size_t i = 0; i < lengthIn; i += 480)
niklase@google.com470e71d2011-07-07 08:21:25 +0000805 {
806 WebRtcSpl_Resample48khzTo16khz(samplesIn + i, tmp + i / 3,
807 (WebRtcSpl_State48khzTo16khz *)state1_,
808 tmp_mem);
809 }
810 outLen = lengthIn / 3;
811 free(tmp_mem);
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000812 WebRtcSpl_DownsampleBy2(tmp, outLen, samplesOut, (int32_t*)state2_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000813 free(tmp);
814 outLen = outLen / 2;
815 return 0;
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000816 case kResamplerMode12To1:
817 // We can only handle blocks of 480 samples
818 // Can be fixed, but I don't think it's needed
819 if ((lengthIn % 480) != 0) {
820 return -1;
821 }
822 if (maxLen < (lengthIn / 12)) {
823 return -1;
824 }
825
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000826 tmp_mem = (int32_t*) malloc(496 * sizeof(int32_t));
827 tmp = (int16_t*) malloc((sizeof(int16_t) * lengthIn) / 3);
828 tmp_2 = (int16_t*) malloc((sizeof(int16_t) * lengthIn) / 6);
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000829 // 12:4
Peter Kastingdce40cf2015-08-24 14:52:23 -0700830 for (size_t i = 0; i < lengthIn; i += 480) {
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000831 // WebRtcSpl_Resample48khzTo16khz() takes a block of 480 samples
832 // as input and outputs a resampled block of 160 samples. The
833 // data is now actually in 96 kHz sampling rate, despite the
834 // function name, and with a resampling factor of 1/3 becomes
835 // 32 kHz.
836 WebRtcSpl_Resample48khzTo16khz(samplesIn + i, tmp + i / 3,
837 (WebRtcSpl_State48khzTo16khz*) state1_,
838 tmp_mem);
839 }
840 outLen = lengthIn / 3;
841 free(tmp_mem);
842 // 4:2
Peter Kasting728d9032015-06-11 14:31:38 -0700843 WebRtcSpl_DownsampleBy2(tmp, outLen, tmp_2, (int32_t*) state2_);
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000844 outLen = outLen / 2;
845 free(tmp);
846 // 2:1
847 WebRtcSpl_DownsampleBy2(tmp_2, outLen, samplesOut,
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000848 (int32_t*) state3_);
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +0000849 free(tmp_2);
850 outLen = outLen / 2;
851 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000852 case kResamplerMode3To2:
853 if (maxLen < (lengthIn * 2 / 3))
854 {
855 return -1;
856 }
857 // 3:6
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000858 tmp = static_cast<int16_t*> (malloc(sizeof(int16_t) * lengthIn * 2));
859 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (int32_t*)state1_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000860 lengthIn *= 2;
861 // 6:2
862 // We can only handle blocks of 480 samples
863 // Can be fixed, but I don't think it's needed
864 if ((lengthIn % 480) != 0)
865 {
866 free(tmp);
867 return -1;
868 }
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000869 tmp_mem = (int32_t*)malloc(496 * sizeof(int32_t));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700870 for (size_t i = 0; i < lengthIn; i += 480)
niklase@google.com470e71d2011-07-07 08:21:25 +0000871 {
872 WebRtcSpl_Resample48khzTo16khz(tmp + i, samplesOut + i / 3,
873 (WebRtcSpl_State48khzTo16khz *)state2_,
874 tmp_mem);
875 }
876 outLen = lengthIn / 3;
877 free(tmp);
878 free(tmp_mem);
879 return 0;
880 case kResamplerMode11To2:
881 // We can only handle blocks of 220 samples
882 // Can be fixed, but I don't think it's needed
883 if ((lengthIn % 220) != 0)
884 {
885 return -1;
886 }
887 if (maxLen < ((lengthIn * 2) / 11))
888 {
889 return -1;
890 }
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000891 tmp_mem = (int32_t*)malloc(126 * sizeof(int32_t));
892 tmp = (int16_t*)malloc((lengthIn * 4) / 11 * sizeof(int16_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000893
Peter Kastingdce40cf2015-08-24 14:52:23 -0700894 for (size_t i = 0; i < lengthIn; i += 220)
niklase@google.com470e71d2011-07-07 08:21:25 +0000895 {
896 WebRtcSpl_Resample22khzTo8khz(samplesIn + i, tmp + (i * 4) / 11,
897 (WebRtcSpl_State22khzTo8khz *)state1_,
898 tmp_mem);
899 }
900 lengthIn = (lengthIn * 4) / 11;
901
Peter Kasting728d9032015-06-11 14:31:38 -0700902 WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut,
903 (int32_t*)state2_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000904 outLen = lengthIn / 2;
905
906 free(tmp_mem);
907 free(tmp);
908 return 0;
909 case kResamplerMode11To4:
910 // We can only handle blocks of 220 samples
911 // Can be fixed, but I don't think it's needed
912 if ((lengthIn % 220) != 0)
913 {
914 return -1;
915 }
916 if (maxLen < ((lengthIn * 4) / 11))
917 {
918 return -1;
919 }
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000920 tmp_mem = (int32_t*)malloc(126 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000921
Peter Kastingdce40cf2015-08-24 14:52:23 -0700922 for (size_t i = 0; i < lengthIn; i += 220)
niklase@google.com470e71d2011-07-07 08:21:25 +0000923 {
924 WebRtcSpl_Resample22khzTo8khz(samplesIn + i, samplesOut + (i * 4) / 11,
925 (WebRtcSpl_State22khzTo8khz *)state1_,
926 tmp_mem);
927 }
928 outLen = (lengthIn * 4) / 11;
929 free(tmp_mem);
930 return 0;
931 case kResamplerMode11To8:
932 // We can only handle blocks of 160 samples
933 // Can be fixed, but I don't think it's needed
934 if ((lengthIn % 220) != 0)
935 {
936 return -1;
937 }
938 if (maxLen < ((lengthIn * 8) / 11))
939 {
940 return -1;
941 }
pbos@webrtc.orgb0913072013-04-09 16:40:28 +0000942 tmp_mem = (int32_t*)malloc(104 * sizeof(int32_t));
niklase@google.com470e71d2011-07-07 08:21:25 +0000943
Peter Kastingdce40cf2015-08-24 14:52:23 -0700944 for (size_t i = 0; i < lengthIn; i += 220)
niklase@google.com470e71d2011-07-07 08:21:25 +0000945 {
946 WebRtcSpl_Resample22khzTo16khz(samplesIn + i, samplesOut + (i * 8) / 11,
947 (WebRtcSpl_State22khzTo16khz *)state1_,
948 tmp_mem);
949 }
950 outLen = (lengthIn * 8) / 11;
951 free(tmp_mem);
952 return 0;
953 break;
954
955 }
956 return 0;
957}
958
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000959} // namespace webrtc