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