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