blob: e4d2aa2b61559ed4509970f6e5549a27cff00578 [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
niklase@google.com470e71d2011-07-07 08:21:25 +000011/*
12 * A wrapper for resampling a numerous amount of sampling combinations.
13 */
14
Yves Gerey988cc082018-10-23 12:03:01 +020015#include <stdint.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000016#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),
Yves Gerey665174f2018-06-19 15:03:05 +020040 slave_right_(nullptr) {}
niklase@google.com470e71d2011-07-07 08:21:25 +000041
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
Yves Gerey665174f2018-06-19 15:03:05 +020075 if ((tmpInFreq_kHz != my_in_frequency_khz_) ||
76 (tmpOutFreq_kHz != my_out_frequency_khz_) ||
77 (num_channels != num_channels_)) {
oprypin67fdb802017-03-09 06:25:06 -080078 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) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010086 RTC_LOG(LS_WARNING)
Sam Zackrisson9da7c742017-10-30 10:05:10 +010087 << "Reset() called with unsupported channel count, num_channels = "
88 << num_channels;
89 return -1;
oprypin67fdb802017-03-09 06:25:06 -080090 }
Sam Zackrisson9da7c742017-10-30 10:05:10 +010091 ResamplerMode mode;
92 if (ComputeResamplerMode(inFreq, outFreq, &mode) != 0) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010093 RTC_LOG(LS_WARNING)
94 << "Reset() called with unsupported sample rates, inFreq = " << inFreq
95 << ", outFreq = " << outFreq;
Sam Zackrisson9da7c742017-10-30 10:05:10 +010096 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(
Yves Gerey665174f2018-06-19 15:03:05 +0200193 static_cast<WebRtcSpl_State16khzTo48khz*>(state1_));
oprypin67fdb802017-03-09 06:25:06 -0800194 // 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
Yves Gerey665174f2018-06-19 15:03:05 +0200397int Resampler::Push(const int16_t* samplesIn,
398 size_t lengthIn,
399 int16_t* samplesOut,
400 size_t maxLen,
401 size_t& outLen) {
oprypin67fdb802017-03-09 06:25:06 -0800402 if (num_channels_ == 2) {
403 // Split up the signal and call the slave object for each channel
404 int16_t* left =
405 static_cast<int16_t*>(malloc(lengthIn * sizeof(int16_t) / 2));
406 int16_t* right =
407 static_cast<int16_t*>(malloc(lengthIn * sizeof(int16_t) / 2));
408 int16_t* out_left =
409 static_cast<int16_t*>(malloc(maxLen / 2 * sizeof(int16_t)));
410 int16_t* out_right =
411 static_cast<int16_t*>(malloc(maxLen / 2 * sizeof(int16_t)));
412 int res = 0;
413 for (size_t i = 0; i < lengthIn; i += 2) {
414 left[i >> 1] = samplesIn[i];
415 right[i >> 1] = samplesIn[i + 1];
niklase@google.com470e71d2011-07-07 08:21:25 +0000416 }
417
oprypin67fdb802017-03-09 06:25:06 -0800418 // It's OK to overwrite the local parameter, since it's just a copy
419 lengthIn = lengthIn / 2;
niklase@google.com470e71d2011-07-07 08:21:25 +0000420
oprypin67fdb802017-03-09 06:25:06 -0800421 size_t actualOutLen_left = 0;
422 size_t actualOutLen_right = 0;
423 // Do resampling for right channel
424 res |= slave_left_->Push(left, lengthIn, out_left, maxLen / 2,
425 actualOutLen_left);
426 res |= slave_right_->Push(right, lengthIn, out_right, maxLen / 2,
427 actualOutLen_right);
428 if (res || (actualOutLen_left != actualOutLen_right)) {
429 free(left);
430 free(right);
431 free(out_left);
432 free(out_right);
433 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000434 }
oprypin67fdb802017-03-09 06:25:06 -0800435
436 // Reassemble the signal
437 for (size_t i = 0; i < actualOutLen_left; i++) {
438 samplesOut[i * 2] = out_left[i];
439 samplesOut[i * 2 + 1] = out_right[i];
440 }
441 outLen = 2 * actualOutLen_left;
442
443 free(left);
444 free(right);
445 free(out_left);
446 free(out_right);
447
niklase@google.com470e71d2011-07-07 08:21:25 +0000448 return 0;
oprypin67fdb802017-03-09 06:25:06 -0800449 }
450
451 // Containers for temp samples
452 int16_t* tmp;
453 int16_t* tmp_2;
454 // tmp data for resampling routines
455 int32_t* tmp_mem;
456
457 switch (my_mode_) {
458 case kResamplerMode1To1:
459 memcpy(samplesOut, samplesIn, lengthIn * sizeof(int16_t));
460 outLen = lengthIn;
461 break;
462 case kResamplerMode1To2:
463 if (maxLen < (lengthIn * 2)) {
464 return -1;
465 }
466 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut,
467 static_cast<int32_t*>(state1_));
468 outLen = lengthIn * 2;
469 return 0;
470 case kResamplerMode1To3:
471
472 // We can only handle blocks of 160 samples
473 // Can be fixed, but I don't think it's needed
474 if ((lengthIn % 160) != 0) {
475 return -1;
476 }
477 if (maxLen < (lengthIn * 3)) {
478 return -1;
479 }
480 tmp_mem = static_cast<int32_t*>(malloc(336 * sizeof(int32_t)));
481
482 for (size_t i = 0; i < lengthIn; i += 160) {
483 WebRtcSpl_Resample16khzTo48khz(
484 samplesIn + i, samplesOut + i * 3,
485 static_cast<WebRtcSpl_State16khzTo48khz*>(state1_), tmp_mem);
486 }
487 outLen = lengthIn * 3;
488 free(tmp_mem);
489 return 0;
490 case kResamplerMode1To4:
491 if (maxLen < (lengthIn * 4)) {
492 return -1;
493 }
494
495 tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * 2 * lengthIn));
496 // 1:2
497 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp,
498 static_cast<int32_t*>(state1_));
499 // 2:4
500 WebRtcSpl_UpsampleBy2(tmp, lengthIn * 2, samplesOut,
501 static_cast<int32_t*>(state2_));
502 outLen = lengthIn * 4;
503 free(tmp);
504 return 0;
505 case kResamplerMode1To6:
506 // We can only handle blocks of 80 samples
507 // Can be fixed, but I don't think it's needed
508 if ((lengthIn % 80) != 0) {
509 return -1;
510 }
511 if (maxLen < (lengthIn * 6)) {
512 return -1;
513 }
514
515 // 1:2
516
517 tmp_mem = static_cast<int32_t*>(malloc(336 * sizeof(int32_t)));
518 tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * 2 * lengthIn));
519
520 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp,
521 static_cast<int32_t*>(state1_));
522 outLen = lengthIn * 2;
523
524 for (size_t i = 0; i < outLen; i += 160) {
525 WebRtcSpl_Resample16khzTo48khz(
526 tmp + i, samplesOut + i * 3,
527 static_cast<WebRtcSpl_State16khzTo48khz*>(state2_), tmp_mem);
528 }
529 outLen = outLen * 3;
530 free(tmp_mem);
531 free(tmp);
532
533 return 0;
534 case kResamplerMode1To12:
535 // We can only handle blocks of 40 samples
536 // Can be fixed, but I don't think it's needed
537 if ((lengthIn % 40) != 0) {
538 return -1;
539 }
540 if (maxLen < (lengthIn * 12)) {
541 return -1;
542 }
543
544 tmp_mem = static_cast<int32_t*>(malloc(336 * sizeof(int32_t)));
545 tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * 4 * lengthIn));
546 // 1:2
547 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut,
548 static_cast<int32_t*>(state1_));
549 outLen = lengthIn * 2;
550 // 2:4
551 WebRtcSpl_UpsampleBy2(samplesOut, outLen, tmp,
552 static_cast<int32_t*>(state2_));
553 outLen = outLen * 2;
554 // 4:12
555 for (size_t i = 0; i < outLen; i += 160) {
556 // WebRtcSpl_Resample16khzTo48khz() takes a block of 160 samples
557 // as input and outputs a resampled block of 480 samples. The
558 // data is now actually in 32 kHz sampling rate, despite the
559 // function name, and with a resampling factor of three becomes
560 // 96 kHz.
561 WebRtcSpl_Resample16khzTo48khz(
562 tmp + i, samplesOut + i * 3,
563 static_cast<WebRtcSpl_State16khzTo48khz*>(state3_), tmp_mem);
564 }
565 outLen = outLen * 3;
566 free(tmp_mem);
567 free(tmp);
568
569 return 0;
570 case kResamplerMode2To3:
571 if (maxLen < (lengthIn * 3 / 2)) {
572 return -1;
573 }
574 // 2:6
575 // We can only handle blocks of 160 samples
576 // Can be fixed, but I don't think it's needed
577 if ((lengthIn % 160) != 0) {
578 return -1;
579 }
Yves Gerey665174f2018-06-19 15:03:05 +0200580 tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * lengthIn * 3));
oprypin67fdb802017-03-09 06:25:06 -0800581 tmp_mem = static_cast<int32_t*>(malloc(336 * sizeof(int32_t)));
582 for (size_t i = 0; i < lengthIn; i += 160) {
583 WebRtcSpl_Resample16khzTo48khz(
584 samplesIn + i, tmp + i * 3,
585 static_cast<WebRtcSpl_State16khzTo48khz*>(state1_), tmp_mem);
586 }
587 lengthIn = lengthIn * 3;
588 // 6:3
589 WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut,
590 static_cast<int32_t*>(state2_));
591 outLen = lengthIn / 2;
592 free(tmp);
593 free(tmp_mem);
594 return 0;
595 case kResamplerMode2To11:
596
597 // We can only handle blocks of 80 samples
598 // Can be fixed, but I don't think it's needed
599 if ((lengthIn % 80) != 0) {
600 return -1;
601 }
602 if (maxLen < ((lengthIn * 11) / 2)) {
603 return -1;
604 }
605 tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * 2 * lengthIn));
606 // 1:2
607 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp,
608 static_cast<int32_t*>(state1_));
609 lengthIn *= 2;
610
611 tmp_mem = static_cast<int32_t*>(malloc(98 * sizeof(int32_t)));
612
613 for (size_t i = 0; i < lengthIn; i += 80) {
614 WebRtcSpl_Resample8khzTo22khz(
615 tmp + i, samplesOut + (i * 11) / 4,
616 static_cast<WebRtcSpl_State8khzTo22khz*>(state2_), tmp_mem);
617 }
618 outLen = (lengthIn * 11) / 4;
619 free(tmp_mem);
620 free(tmp);
621 return 0;
622 case kResamplerMode4To11:
623
624 // We can only handle blocks of 80 samples
625 // Can be fixed, but I don't think it's needed
626 if ((lengthIn % 80) != 0) {
627 return -1;
628 }
629 if (maxLen < ((lengthIn * 11) / 4)) {
630 return -1;
631 }
632 tmp_mem = static_cast<int32_t*>(malloc(98 * sizeof(int32_t)));
633
634 for (size_t i = 0; i < lengthIn; i += 80) {
635 WebRtcSpl_Resample8khzTo22khz(
636 samplesIn + i, samplesOut + (i * 11) / 4,
637 static_cast<WebRtcSpl_State8khzTo22khz*>(state1_), tmp_mem);
638 }
639 outLen = (lengthIn * 11) / 4;
640 free(tmp_mem);
641 return 0;
642 case kResamplerMode8To11:
643 // We can only handle blocks of 160 samples
644 // Can be fixed, but I don't think it's needed
645 if ((lengthIn % 160) != 0) {
646 return -1;
647 }
648 if (maxLen < ((lengthIn * 11) / 8)) {
649 return -1;
650 }
651 tmp_mem = static_cast<int32_t*>(malloc(88 * sizeof(int32_t)));
652
653 for (size_t i = 0; i < lengthIn; i += 160) {
654 WebRtcSpl_Resample16khzTo22khz(
655 samplesIn + i, samplesOut + (i * 11) / 8,
656 static_cast<WebRtcSpl_State16khzTo22khz*>(state1_), tmp_mem);
657 }
658 outLen = (lengthIn * 11) / 8;
659 free(tmp_mem);
660 return 0;
661
662 case kResamplerMode11To16:
663 // We can only handle blocks of 110 samples
664 if ((lengthIn % 110) != 0) {
665 return -1;
666 }
667 if (maxLen < ((lengthIn * 16) / 11)) {
668 return -1;
669 }
670
671 tmp_mem = static_cast<int32_t*>(malloc(104 * sizeof(int32_t)));
672 tmp = static_cast<int16_t*>(malloc((sizeof(int16_t) * lengthIn * 2)));
673
674 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp,
675 static_cast<int32_t*>(state1_));
676
677 for (size_t i = 0; i < (lengthIn * 2); i += 220) {
678 WebRtcSpl_Resample22khzTo16khz(
679 tmp + i, samplesOut + (i / 220) * 160,
680 static_cast<WebRtcSpl_State22khzTo16khz*>(state2_), tmp_mem);
681 }
682
683 outLen = (lengthIn * 16) / 11;
684
685 free(tmp_mem);
686 free(tmp);
687 return 0;
688
689 case kResamplerMode11To32:
690
691 // We can only handle blocks of 110 samples
692 if ((lengthIn % 110) != 0) {
693 return -1;
694 }
695 if (maxLen < ((lengthIn * 32) / 11)) {
696 return -1;
697 }
698
699 tmp_mem = static_cast<int32_t*>(malloc(104 * sizeof(int32_t)));
700 tmp = static_cast<int16_t*>(malloc((sizeof(int16_t) * lengthIn * 2)));
701
702 // 11 -> 22 kHz in samplesOut
703 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut,
704 static_cast<int32_t*>(state1_));
705
706 // 22 -> 16 in tmp
707 for (size_t i = 0; i < (lengthIn * 2); i += 220) {
708 WebRtcSpl_Resample22khzTo16khz(
709 samplesOut + i, tmp + (i / 220) * 160,
710 static_cast<WebRtcSpl_State22khzTo16khz*>(state2_), tmp_mem);
711 }
712
713 // 16 -> 32 in samplesOut
714 WebRtcSpl_UpsampleBy2(tmp, (lengthIn * 16) / 11, samplesOut,
715 static_cast<int32_t*>(state3_));
716
717 outLen = (lengthIn * 32) / 11;
718
719 free(tmp_mem);
720 free(tmp);
721 return 0;
722
723 case kResamplerMode2To1:
724 if (maxLen < (lengthIn / 2)) {
725 return -1;
726 }
727 WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, samplesOut,
728 static_cast<int32_t*>(state1_));
729 outLen = lengthIn / 2;
730 return 0;
731 case kResamplerMode3To1:
732 // We can only handle blocks of 480 samples
733 // Can be fixed, but I don't think it's needed
734 if ((lengthIn % 480) != 0) {
735 return -1;
736 }
737 if (maxLen < (lengthIn / 3)) {
738 return -1;
739 }
740 tmp_mem = static_cast<int32_t*>(malloc(496 * sizeof(int32_t)));
741
742 for (size_t i = 0; i < lengthIn; i += 480) {
743 WebRtcSpl_Resample48khzTo16khz(
744 samplesIn + i, samplesOut + i / 3,
745 static_cast<WebRtcSpl_State48khzTo16khz*>(state1_), tmp_mem);
746 }
747 outLen = lengthIn / 3;
748 free(tmp_mem);
749 return 0;
750 case kResamplerMode4To1:
751 if (maxLen < (lengthIn / 4)) {
752 return -1;
753 }
754 tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * lengthIn / 2));
755 // 4:2
756 WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, tmp,
757 static_cast<int32_t*>(state1_));
758 // 2:1
759 WebRtcSpl_DownsampleBy2(tmp, lengthIn / 2, samplesOut,
760 static_cast<int32_t*>(state2_));
761 outLen = lengthIn / 4;
762 free(tmp);
763 return 0;
764
765 case kResamplerMode6To1:
766 // We can only handle blocks of 480 samples
767 // Can be fixed, but I don't think it's needed
768 if ((lengthIn % 480) != 0) {
769 return -1;
770 }
771 if (maxLen < (lengthIn / 6)) {
772 return -1;
773 }
774
775 tmp_mem = static_cast<int32_t*>(malloc(496 * sizeof(int32_t)));
776 tmp = static_cast<int16_t*>(malloc((sizeof(int16_t) * lengthIn) / 3));
777
778 for (size_t i = 0; i < lengthIn; i += 480) {
779 WebRtcSpl_Resample48khzTo16khz(
780 samplesIn + i, tmp + i / 3,
781 static_cast<WebRtcSpl_State48khzTo16khz*>(state1_), tmp_mem);
782 }
783 outLen = lengthIn / 3;
784 free(tmp_mem);
785 WebRtcSpl_DownsampleBy2(tmp, outLen, samplesOut,
786 static_cast<int32_t*>(state2_));
787 free(tmp);
788 outLen = outLen / 2;
789 return 0;
790 case kResamplerMode12To1:
791 // We can only handle blocks of 480 samples
792 // Can be fixed, but I don't think it's needed
793 if ((lengthIn % 480) != 0) {
794 return -1;
795 }
796 if (maxLen < (lengthIn / 12)) {
797 return -1;
798 }
799
800 tmp_mem = static_cast<int32_t*>(malloc(496 * sizeof(int32_t)));
801 tmp = static_cast<int16_t*>(malloc((sizeof(int16_t) * lengthIn) / 3));
802 tmp_2 = static_cast<int16_t*>(malloc((sizeof(int16_t) * lengthIn) / 6));
803 // 12:4
804 for (size_t i = 0; i < lengthIn; i += 480) {
805 // WebRtcSpl_Resample48khzTo16khz() takes a block of 480 samples
806 // as input and outputs a resampled block of 160 samples. The
807 // data is now actually in 96 kHz sampling rate, despite the
808 // function name, and with a resampling factor of 1/3 becomes
809 // 32 kHz.
810 WebRtcSpl_Resample48khzTo16khz(
811 samplesIn + i, tmp + i / 3,
812 static_cast<WebRtcSpl_State48khzTo16khz*>(state1_), tmp_mem);
813 }
814 outLen = lengthIn / 3;
815 free(tmp_mem);
816 // 4:2
817 WebRtcSpl_DownsampleBy2(tmp, outLen, tmp_2,
818 static_cast<int32_t*>(state2_));
819 outLen = outLen / 2;
820 free(tmp);
821 // 2:1
822 WebRtcSpl_DownsampleBy2(tmp_2, outLen, samplesOut,
823 static_cast<int32_t*>(state3_));
824 free(tmp_2);
825 outLen = outLen / 2;
826 return 0;
827 case kResamplerMode3To2:
828 if (maxLen < (lengthIn * 2 / 3)) {
829 return -1;
830 }
831 // 3:6
Yves Gerey665174f2018-06-19 15:03:05 +0200832 tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * lengthIn * 2));
oprypin67fdb802017-03-09 06:25:06 -0800833 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp,
834 static_cast<int32_t*>(state1_));
835 lengthIn *= 2;
836 // 6:2
837 // We can only handle blocks of 480 samples
838 // Can be fixed, but I don't think it's needed
839 if ((lengthIn % 480) != 0) {
840 free(tmp);
841 return -1;
842 }
843 tmp_mem = static_cast<int32_t*>(malloc(496 * sizeof(int32_t)));
844 for (size_t i = 0; i < lengthIn; i += 480) {
845 WebRtcSpl_Resample48khzTo16khz(
846 tmp + i, samplesOut + i / 3,
847 static_cast<WebRtcSpl_State48khzTo16khz*>(state2_), tmp_mem);
848 }
849 outLen = lengthIn / 3;
850 free(tmp);
851 free(tmp_mem);
852 return 0;
853 case kResamplerMode11To2:
854 // We can only handle blocks of 220 samples
855 // Can be fixed, but I don't think it's needed
856 if ((lengthIn % 220) != 0) {
857 return -1;
858 }
859 if (maxLen < ((lengthIn * 2) / 11)) {
860 return -1;
861 }
862 tmp_mem = static_cast<int32_t*>(malloc(126 * sizeof(int32_t)));
Yves Gerey665174f2018-06-19 15:03:05 +0200863 tmp =
864 static_cast<int16_t*>(malloc((lengthIn * 4) / 11 * sizeof(int16_t)));
oprypin67fdb802017-03-09 06:25:06 -0800865
866 for (size_t i = 0; i < lengthIn; i += 220) {
867 WebRtcSpl_Resample22khzTo8khz(
868 samplesIn + i, tmp + (i * 4) / 11,
869 static_cast<WebRtcSpl_State22khzTo8khz*>(state1_), tmp_mem);
870 }
871 lengthIn = (lengthIn * 4) / 11;
872
873 WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut,
874 static_cast<int32_t*>(state2_));
875 outLen = lengthIn / 2;
876
877 free(tmp_mem);
878 free(tmp);
879 return 0;
880 case kResamplerMode11To4:
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 return -1;
885 }
886 if (maxLen < ((lengthIn * 4) / 11)) {
887 return -1;
888 }
889 tmp_mem = static_cast<int32_t*>(malloc(126 * sizeof(int32_t)));
890
891 for (size_t i = 0; i < lengthIn; i += 220) {
892 WebRtcSpl_Resample22khzTo8khz(
893 samplesIn + i, samplesOut + (i * 4) / 11,
894 static_cast<WebRtcSpl_State22khzTo8khz*>(state1_), tmp_mem);
895 }
896 outLen = (lengthIn * 4) / 11;
897 free(tmp_mem);
898 return 0;
899 case kResamplerMode11To8:
900 // We can only handle blocks of 160 samples
901 // Can be fixed, but I don't think it's needed
902 if ((lengthIn % 220) != 0) {
903 return -1;
904 }
905 if (maxLen < ((lengthIn * 8) / 11)) {
906 return -1;
907 }
908 tmp_mem = static_cast<int32_t*>(malloc(104 * sizeof(int32_t)));
909
910 for (size_t i = 0; i < lengthIn; i += 220) {
911 WebRtcSpl_Resample22khzTo16khz(
912 samplesIn + i, samplesOut + (i * 8) / 11,
913 static_cast<WebRtcSpl_State22khzTo16khz*>(state1_), tmp_mem);
914 }
915 outLen = (lengthIn * 8) / 11;
916 free(tmp_mem);
917 return 0;
918 break;
919 }
920 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000921}
922
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000923} // namespace webrtc