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