1 /*
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
19 #include "signal_processing_library.h"
20 #include "resampler.h"
21
22
23 namespace webrtc
24 {
25
Resampler()26 Resampler::Resampler()
27 {
28 state1_ = NULL;
29 state2_ = NULL;
30 state3_ = NULL;
31 in_buffer_ = NULL;
32 out_buffer_ = NULL;
33 in_buffer_size_ = 0;
34 out_buffer_size_ = 0;
35 in_buffer_size_max_ = 0;
36 out_buffer_size_max_ = 0;
37 // we need a reset before we will work
38 my_in_frequency_khz_ = 0;
39 my_out_frequency_khz_ = 0;
40 my_mode_ = kResamplerMode1To1;
41 my_type_ = kResamplerInvalid;
42 slave_left_ = NULL;
43 slave_right_ = NULL;
44 }
45
Resampler(int inFreq,int outFreq,ResamplerType type)46 Resampler::Resampler(int inFreq, int outFreq, ResamplerType type)
47 {
48 state1_ = NULL;
49 state2_ = NULL;
50 state3_ = NULL;
51 in_buffer_ = NULL;
52 out_buffer_ = NULL;
53 in_buffer_size_ = 0;
54 out_buffer_size_ = 0;
55 in_buffer_size_max_ = 0;
56 out_buffer_size_max_ = 0;
57 // we need a reset before we will work
58 my_in_frequency_khz_ = 0;
59 my_out_frequency_khz_ = 0;
60 my_mode_ = kResamplerMode1To1;
61 my_type_ = kResamplerInvalid;
62 slave_left_ = NULL;
63 slave_right_ = NULL;
64
65 int res = Reset(inFreq, outFreq, type);
66
67 }
68
~Resampler()69 Resampler::~Resampler()
70 {
71 if (state1_)
72 {
73 free(state1_);
74 }
75 if (state2_)
76 {
77 free(state2_);
78 }
79 if (state3_)
80 {
81 free(state3_);
82 }
83 if (in_buffer_)
84 {
85 free(in_buffer_);
86 }
87 if (out_buffer_)
88 {
89 free(out_buffer_);
90 }
91 if (slave_left_)
92 {
93 delete slave_left_;
94 }
95 if (slave_right_)
96 {
97 delete slave_right_;
98 }
99 }
100
ResetIfNeeded(int inFreq,int outFreq,ResamplerType type)101 int Resampler::ResetIfNeeded(int inFreq, int outFreq, ResamplerType type)
102 {
103 int tmpInFreq_kHz = inFreq / 1000;
104 int tmpOutFreq_kHz = outFreq / 1000;
105
106 if ((tmpInFreq_kHz != my_in_frequency_khz_) || (tmpOutFreq_kHz != my_out_frequency_khz_)
107 || (type != my_type_))
108 {
109 return Reset(inFreq, outFreq, type);
110 } else
111 {
112 return 0;
113 }
114 }
115
Reset(int inFreq,int outFreq,ResamplerType type)116 int Resampler::Reset(int inFreq, int outFreq, ResamplerType type)
117 {
118
119 if (state1_)
120 {
121 free(state1_);
122 state1_ = NULL;
123 }
124 if (state2_)
125 {
126 free(state2_);
127 state2_ = NULL;
128 }
129 if (state3_)
130 {
131 free(state3_);
132 state3_ = NULL;
133 }
134 if (in_buffer_)
135 {
136 free(in_buffer_);
137 in_buffer_ = NULL;
138 }
139 if (out_buffer_)
140 {
141 free(out_buffer_);
142 out_buffer_ = NULL;
143 }
144 if (slave_left_)
145 {
146 delete slave_left_;
147 slave_left_ = NULL;
148 }
149 if (slave_right_)
150 {
151 delete slave_right_;
152 slave_right_ = NULL;
153 }
154
155 in_buffer_size_ = 0;
156 out_buffer_size_ = 0;
157 in_buffer_size_max_ = 0;
158 out_buffer_size_max_ = 0;
159
160 // This might be overridden if parameters are not accepted.
161 my_type_ = type;
162
163 // Start with a math exercise, Euclid's algorithm to find the gcd:
164
165 int a = inFreq;
166 int b = outFreq;
167 int c = a % b;
168 while (c != 0)
169 {
170 a = b;
171 b = c;
172 c = a % b;
173 }
174 // b is now the gcd;
175
176 // We need to track what domain we're in.
177 my_in_frequency_khz_ = inFreq / 1000;
178 my_out_frequency_khz_ = outFreq / 1000;
179
180 // Scale with GCD
181 inFreq = inFreq / b;
182 outFreq = outFreq / b;
183
184 // Do we need stereo?
185 if ((my_type_ & 0xf0) == 0x20)
186 {
187 // Change type to mono
188 type = (ResamplerType)((int)type & 0x0f + 0x10);
189 slave_left_ = new Resampler(inFreq, outFreq, type);
190 slave_right_ = new Resampler(inFreq, outFreq, type);
191 }
192
193 if (inFreq == outFreq)
194 {
195 my_mode_ = kResamplerMode1To1;
196 } else if (inFreq == 1)
197 {
198 switch (outFreq)
199 {
200 case 2:
201 my_mode_ = kResamplerMode1To2;
202 break;
203 case 3:
204 my_mode_ = kResamplerMode1To3;
205 break;
206 case 4:
207 my_mode_ = kResamplerMode1To4;
208 break;
209 case 6:
210 my_mode_ = kResamplerMode1To6;
211 break;
212 default:
213 my_type_ = kResamplerInvalid;
214 break;
215 }
216 } else if (outFreq == 1)
217 {
218 switch (inFreq)
219 {
220 case 2:
221 my_mode_ = kResamplerMode2To1;
222 break;
223 case 3:
224 my_mode_ = kResamplerMode3To1;
225 break;
226 case 4:
227 my_mode_ = kResamplerMode4To1;
228 break;
229 case 6:
230 my_mode_ = kResamplerMode6To1;
231 break;
232 default:
233 my_type_ = kResamplerInvalid;
234 break;
235 }
236 } else if ((inFreq == 2) && (outFreq == 3))
237 {
238 my_mode_ = kResamplerMode2To3;
239 } else if ((inFreq == 2) && (outFreq == 11))
240 {
241 my_mode_ = kResamplerMode2To11;
242 } else if ((inFreq == 4) && (outFreq == 11))
243 {
244 my_mode_ = kResamplerMode4To11;
245 } else if ((inFreq == 8) && (outFreq == 11))
246 {
247 my_mode_ = kResamplerMode8To11;
248 } else if ((inFreq == 3) && (outFreq == 2))
249 {
250 my_mode_ = kResamplerMode3To2;
251 } else if ((inFreq == 11) && (outFreq == 2))
252 {
253 my_mode_ = kResamplerMode11To2;
254 } else if ((inFreq == 11) && (outFreq == 4))
255 {
256 my_mode_ = kResamplerMode11To4;
257 } else if ((inFreq == 11) && (outFreq == 16))
258 {
259 my_mode_ = kResamplerMode11To16;
260 } else if ((inFreq == 11) && (outFreq == 32))
261 {
262 my_mode_ = kResamplerMode11To32;
263 } else if ((inFreq == 11) && (outFreq == 8))
264 {
265 my_mode_ = kResamplerMode11To8;
266 } else
267 {
268 my_type_ = kResamplerInvalid;
269 return -1;
270 }
271
272 // Now create the states we need
273 switch (my_mode_)
274 {
275 case kResamplerMode1To1:
276 // No state needed;
277 break;
278 case kResamplerMode1To2:
279 state1_ = malloc(8 * sizeof(WebRtc_Word32));
280 memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
281 break;
282 case kResamplerMode1To3:
283 state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
284 WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state1_);
285 break;
286 case kResamplerMode1To4:
287 // 1:2
288 state1_ = malloc(8 * sizeof(WebRtc_Word32));
289 memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
290 // 2:4
291 state2_ = malloc(8 * sizeof(WebRtc_Word32));
292 memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
293 break;
294 case kResamplerMode1To6:
295 // 1:2
296 state1_ = malloc(8 * sizeof(WebRtc_Word32));
297 memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
298 // 2:6
299 state2_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
300 WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state2_);
301 break;
302 case kResamplerMode2To3:
303 // 2:6
304 state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
305 WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state1_);
306 // 6:3
307 state2_ = malloc(8 * sizeof(WebRtc_Word32));
308 memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
309 break;
310 case kResamplerMode2To11:
311 state1_ = malloc(8 * sizeof(WebRtc_Word32));
312 memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
313
314 state2_ = malloc(sizeof(WebRtcSpl_State8khzTo22khz));
315 WebRtcSpl_ResetResample8khzTo22khz((WebRtcSpl_State8khzTo22khz *)state2_);
316 break;
317 case kResamplerMode4To11:
318 state1_ = malloc(sizeof(WebRtcSpl_State8khzTo22khz));
319 WebRtcSpl_ResetResample8khzTo22khz((WebRtcSpl_State8khzTo22khz *)state1_);
320 break;
321 case kResamplerMode8To11:
322 state1_ = malloc(sizeof(WebRtcSpl_State16khzTo22khz));
323 WebRtcSpl_ResetResample16khzTo22khz((WebRtcSpl_State16khzTo22khz *)state1_);
324 break;
325 case kResamplerMode11To16:
326 state1_ = malloc(8 * sizeof(WebRtc_Word32));
327 memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
328
329 state2_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz));
330 WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state2_);
331 break;
332 case kResamplerMode11To32:
333 // 11 -> 22
334 state1_ = malloc(8 * sizeof(WebRtc_Word32));
335 memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
336
337 // 22 -> 16
338 state2_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz));
339 WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state2_);
340
341 // 16 -> 32
342 state3_ = malloc(8 * sizeof(WebRtc_Word32));
343 memset(state3_, 0, 8 * sizeof(WebRtc_Word32));
344
345 break;
346 case kResamplerMode2To1:
347 state1_ = malloc(8 * sizeof(WebRtc_Word32));
348 memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
349 break;
350 case kResamplerMode3To1:
351 state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
352 WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state1_);
353 break;
354 case kResamplerMode4To1:
355 // 4:2
356 state1_ = malloc(8 * sizeof(WebRtc_Word32));
357 memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
358 // 2:1
359 state2_ = malloc(8 * sizeof(WebRtc_Word32));
360 memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
361 break;
362 case kResamplerMode6To1:
363 // 6:2
364 state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
365 WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state1_);
366 // 2:1
367 state2_ = malloc(8 * sizeof(WebRtc_Word32));
368 memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
369 break;
370 case kResamplerMode3To2:
371 // 3:6
372 state1_ = malloc(8 * sizeof(WebRtc_Word32));
373 memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
374 // 6:2
375 state2_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
376 WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state2_);
377 break;
378 case kResamplerMode11To2:
379 state1_ = malloc(sizeof(WebRtcSpl_State22khzTo8khz));
380 WebRtcSpl_ResetResample22khzTo8khz((WebRtcSpl_State22khzTo8khz *)state1_);
381
382 state2_ = malloc(8 * sizeof(WebRtc_Word32));
383 memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
384
385 break;
386 case kResamplerMode11To4:
387 state1_ = malloc(sizeof(WebRtcSpl_State22khzTo8khz));
388 WebRtcSpl_ResetResample22khzTo8khz((WebRtcSpl_State22khzTo8khz *)state1_);
389 break;
390 case kResamplerMode11To8:
391 state1_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz));
392 WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state1_);
393 break;
394
395 }
396
397 return 0;
398 }
399
400 // Synchronous resampling, all output samples are written to samplesOut
Push(const WebRtc_Word16 * samplesIn,int lengthIn,WebRtc_Word16 * samplesOut,int maxLen,int & outLen)401 int Resampler::Push(const WebRtc_Word16 * samplesIn, int lengthIn, WebRtc_Word16* samplesOut,
402 int maxLen, int &outLen)
403 {
404 // Check that the resampler is not in asynchronous mode
405 if (my_type_ & 0x0f)
406 {
407 return -1;
408 }
409
410 // Do we have a stereo signal?
411 if ((my_type_ & 0xf0) == 0x20)
412 {
413
414 // Split up the signal and call the slave object for each channel
415
416 WebRtc_Word16* left = (WebRtc_Word16*)malloc(lengthIn * sizeof(WebRtc_Word16) / 2);
417 WebRtc_Word16* right = (WebRtc_Word16*)malloc(lengthIn * sizeof(WebRtc_Word16) / 2);
418 WebRtc_Word16* out_left = (WebRtc_Word16*)malloc(maxLen / 2 * sizeof(WebRtc_Word16));
419 WebRtc_Word16* out_right =
420 (WebRtc_Word16*)malloc(maxLen / 2 * sizeof(WebRtc_Word16));
421 int res = 0;
422 for (int i = 0; i < lengthIn; i += 2)
423 {
424 left[i >> 1] = samplesIn[i];
425 right[i >> 1] = samplesIn[i + 1];
426 }
427
428 // It's OK to overwrite the local parameter, since it's just a copy
429 lengthIn = lengthIn / 2;
430
431 int actualOutLen_left = 0;
432 int actualOutLen_right = 0;
433 // Do resampling for right channel
434 res |= slave_left_->Push(left, lengthIn, out_left, maxLen / 2, actualOutLen_left);
435 res |= slave_right_->Push(right, lengthIn, out_right, maxLen / 2, actualOutLen_right);
436 if (res || (actualOutLen_left != actualOutLen_right))
437 {
438 free(left);
439 free(right);
440 free(out_left);
441 free(out_right);
442 return -1;
443 }
444
445 // Reassemble the signal
446 for (int i = 0; i < actualOutLen_left; i++)
447 {
448 samplesOut[i * 2] = out_left[i];
449 samplesOut[i * 2 + 1] = out_right[i];
450 }
451 outLen = 2 * actualOutLen_left;
452
453 free(left);
454 free(right);
455 free(out_left);
456 free(out_right);
457
458 return 0;
459 }
460
461 // Container for temp samples
462 WebRtc_Word16* tmp;
463 // tmp data for resampling routines
464 WebRtc_Word32* tmp_mem;
465
466 switch (my_mode_)
467 {
468 case kResamplerMode1To1:
469 memcpy(samplesOut, samplesIn, lengthIn * sizeof(WebRtc_Word16));
470 outLen = lengthIn;
471 break;
472 case kResamplerMode1To2:
473 if (maxLen < (lengthIn * 2))
474 {
475 return -1;
476 }
477 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, (WebRtc_Word32*)state1_);
478 outLen = lengthIn * 2;
479 return 0;
480 case kResamplerMode1To3:
481
482 // We can only handle blocks of 160 samples
483 // Can be fixed, but I don't think it's needed
484 if ((lengthIn % 160) != 0)
485 {
486 return -1;
487 }
488 if (maxLen < (lengthIn * 3))
489 {
490 return -1;
491 }
492 tmp_mem = (WebRtc_Word32*)malloc(336 * sizeof(WebRtc_Word32));
493
494 for (int i = 0; i < lengthIn; i += 160)
495 {
496 WebRtcSpl_Resample16khzTo48khz(samplesIn + i, samplesOut + i * 3,
497 (WebRtcSpl_State16khzTo48khz *)state1_,
498 tmp_mem);
499 }
500 outLen = lengthIn * 3;
501 free(tmp_mem);
502 return 0;
503 case kResamplerMode1To4:
504 if (maxLen < (lengthIn * 4))
505 {
506 return -1;
507 }
508
509 tmp = (WebRtc_Word16*)malloc(sizeof(WebRtc_Word16) * 2 * lengthIn);
510 // 1:2
511 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
512 // 2:4
513 WebRtcSpl_UpsampleBy2(tmp, lengthIn * 2, samplesOut, (WebRtc_Word32*)state2_);
514 outLen = lengthIn * 4;
515 free(tmp);
516 return 0;
517 case kResamplerMode1To6:
518 // We can only handle blocks of 80 samples
519 // Can be fixed, but I don't think it's needed
520 if ((lengthIn % 80) != 0)
521 {
522 return -1;
523 }
524 if (maxLen < (lengthIn * 6))
525 {
526 return -1;
527 }
528
529 //1:2
530
531 tmp_mem = (WebRtc_Word32*)malloc(336 * sizeof(WebRtc_Word32));
532 tmp = (WebRtc_Word16*)malloc(sizeof(WebRtc_Word16) * 2 * lengthIn);
533
534 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
535 outLen = lengthIn * 2;
536
537 for (int i = 0; i < outLen; i += 160)
538 {
539 WebRtcSpl_Resample16khzTo48khz(tmp + i, samplesOut + i * 3,
540 (WebRtcSpl_State16khzTo48khz *)state2_,
541 tmp_mem);
542 }
543 outLen = outLen * 3;
544 free(tmp_mem);
545 free(tmp);
546
547 return 0;
548 case kResamplerMode2To3:
549 if (maxLen < (lengthIn * 3 / 2))
550 {
551 return -1;
552 }
553 // 2:6
554 // We can only handle blocks of 160 samples
555 // Can be fixed, but I don't think it's needed
556 if ((lengthIn % 160) != 0)
557 {
558 return -1;
559 }
560 tmp = static_cast<WebRtc_Word16*> (malloc(sizeof(WebRtc_Word16) * lengthIn * 3));
561 tmp_mem = (WebRtc_Word32*)malloc(336 * sizeof(WebRtc_Word32));
562 for (int i = 0; i < lengthIn; i += 160)
563 {
564 WebRtcSpl_Resample16khzTo48khz(samplesIn + i, tmp + i * 3,
565 (WebRtcSpl_State16khzTo48khz *)state1_,
566 tmp_mem);
567 }
568 lengthIn = lengthIn * 3;
569 // 6:3
570 WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut, (WebRtc_Word32*)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 {
581 return -1;
582 }
583 if (maxLen < ((lengthIn * 11) / 2))
584 {
585 return -1;
586 }
587 tmp = (WebRtc_Word16*)malloc(sizeof(WebRtc_Word16) * 2 * lengthIn);
588 // 1:2
589 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
590 lengthIn *= 2;
591
592 tmp_mem = (WebRtc_Word32*)malloc(98 * sizeof(WebRtc_Word32));
593
594 for (int i = 0; i < lengthIn; i += 80)
595 {
596 WebRtcSpl_Resample8khzTo22khz(tmp + i, samplesOut + (i * 11) / 4,
597 (WebRtcSpl_State8khzTo22khz *)state2_,
598 tmp_mem);
599 }
600 outLen = (lengthIn * 11) / 4;
601 free(tmp_mem);
602 free(tmp);
603 return 0;
604 case kResamplerMode4To11:
605
606 // We can only handle blocks of 80 samples
607 // Can be fixed, but I don't think it's needed
608 if ((lengthIn % 80) != 0)
609 {
610 return -1;
611 }
612 if (maxLen < ((lengthIn * 11) / 4))
613 {
614 return -1;
615 }
616 tmp_mem = (WebRtc_Word32*)malloc(98 * sizeof(WebRtc_Word32));
617
618 for (int i = 0; i < lengthIn; i += 80)
619 {
620 WebRtcSpl_Resample8khzTo22khz(samplesIn + i, samplesOut + (i * 11) / 4,
621 (WebRtcSpl_State8khzTo22khz *)state1_,
622 tmp_mem);
623 }
624 outLen = (lengthIn * 11) / 4;
625 free(tmp_mem);
626 return 0;
627 case kResamplerMode8To11:
628 // We can only handle blocks of 160 samples
629 // Can be fixed, but I don't think it's needed
630 if ((lengthIn % 160) != 0)
631 {
632 return -1;
633 }
634 if (maxLen < ((lengthIn * 11) / 8))
635 {
636 return -1;
637 }
638 tmp_mem = (WebRtc_Word32*)malloc(88 * sizeof(WebRtc_Word32));
639
640 for (int i = 0; i < lengthIn; i += 160)
641 {
642 WebRtcSpl_Resample16khzTo22khz(samplesIn + i, samplesOut + (i * 11) / 8,
643 (WebRtcSpl_State16khzTo22khz *)state1_,
644 tmp_mem);
645 }
646 outLen = (lengthIn * 11) / 8;
647 free(tmp_mem);
648 return 0;
649
650 case kResamplerMode11To16:
651 // We can only handle blocks of 110 samples
652 if ((lengthIn % 110) != 0)
653 {
654 return -1;
655 }
656 if (maxLen < ((lengthIn * 16) / 11))
657 {
658 return -1;
659 }
660
661 tmp_mem = (WebRtc_Word32*)malloc(104 * sizeof(WebRtc_Word32));
662 tmp = (WebRtc_Word16*)malloc((sizeof(WebRtc_Word16) * lengthIn * 2));
663
664 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
665
666 for (int i = 0; i < (lengthIn * 2); i += 220)
667 {
668 WebRtcSpl_Resample22khzTo16khz(tmp + i, samplesOut + (i / 220) * 160,
669 (WebRtcSpl_State22khzTo16khz *)state2_,
670 tmp_mem);
671 }
672
673 outLen = (lengthIn * 16) / 11;
674
675 free(tmp_mem);
676 free(tmp);
677 return 0;
678
679 case kResamplerMode11To32:
680
681 // We can only handle blocks of 110 samples
682 if ((lengthIn % 110) != 0)
683 {
684 return -1;
685 }
686 if (maxLen < ((lengthIn * 32) / 11))
687 {
688 return -1;
689 }
690
691 tmp_mem = (WebRtc_Word32*)malloc(104 * sizeof(WebRtc_Word32));
692 tmp = (WebRtc_Word16*)malloc((sizeof(WebRtc_Word16) * lengthIn * 2));
693
694 // 11 -> 22 kHz in samplesOut
695 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, (WebRtc_Word32*)state1_);
696
697 // 22 -> 16 in tmp
698 for (int i = 0; i < (lengthIn * 2); i += 220)
699 {
700 WebRtcSpl_Resample22khzTo16khz(samplesOut + i, tmp + (i / 220) * 160,
701 (WebRtcSpl_State22khzTo16khz *)state2_,
702 tmp_mem);
703 }
704
705 // 16 -> 32 in samplesOut
706 WebRtcSpl_UpsampleBy2(tmp, (lengthIn * 16) / 11, samplesOut,
707 (WebRtc_Word32*)state3_);
708
709 outLen = (lengthIn * 32) / 11;
710
711 free(tmp_mem);
712 free(tmp);
713 return 0;
714
715 case kResamplerMode2To1:
716 if (maxLen < (lengthIn / 2))
717 {
718 return -1;
719 }
720 WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, samplesOut, (WebRtc_Word32*)state1_);
721 outLen = lengthIn / 2;
722 return 0;
723 case kResamplerMode3To1:
724 // We can only handle blocks of 480 samples
725 // Can be fixed, but I don't think it's needed
726 if ((lengthIn % 480) != 0)
727 {
728 return -1;
729 }
730 if (maxLen < (lengthIn / 3))
731 {
732 return -1;
733 }
734 tmp_mem = (WebRtc_Word32*)malloc(496 * sizeof(WebRtc_Word32));
735
736 for (int i = 0; i < lengthIn; i += 480)
737 {
738 WebRtcSpl_Resample48khzTo16khz(samplesIn + i, samplesOut + i / 3,
739 (WebRtcSpl_State48khzTo16khz *)state1_,
740 tmp_mem);
741 }
742 outLen = lengthIn / 3;
743 free(tmp_mem);
744 return 0;
745 case kResamplerMode4To1:
746 if (maxLen < (lengthIn / 4))
747 {
748 return -1;
749 }
750 tmp = (WebRtc_Word16*)malloc(sizeof(WebRtc_Word16) * lengthIn / 2);
751 // 4:2
752 WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
753 // 2:1
754 WebRtcSpl_DownsampleBy2(tmp, lengthIn / 2, samplesOut, (WebRtc_Word32*)state2_);
755 outLen = lengthIn / 4;
756 free(tmp);
757 return 0;
758
759 case kResamplerMode6To1:
760 // We can only handle blocks of 480 samples
761 // Can be fixed, but I don't think it's needed
762 if ((lengthIn % 480) != 0)
763 {
764 return -1;
765 }
766 if (maxLen < (lengthIn / 6))
767 {
768 return -1;
769 }
770
771 tmp_mem = (WebRtc_Word32*)malloc(496 * sizeof(WebRtc_Word32));
772 tmp = (WebRtc_Word16*)malloc((sizeof(WebRtc_Word16) * lengthIn) / 3);
773
774 for (int i = 0; i < lengthIn; i += 480)
775 {
776 WebRtcSpl_Resample48khzTo16khz(samplesIn + i, tmp + i / 3,
777 (WebRtcSpl_State48khzTo16khz *)state1_,
778 tmp_mem);
779 }
780 outLen = lengthIn / 3;
781 free(tmp_mem);
782 WebRtcSpl_DownsampleBy2(tmp, outLen, samplesOut, (WebRtc_Word32*)state2_);
783 free(tmp);
784 outLen = outLen / 2;
785 return 0;
786 case kResamplerMode3To2:
787 if (maxLen < (lengthIn * 2 / 3))
788 {
789 return -1;
790 }
791 // 3:6
792 tmp = static_cast<WebRtc_Word16*> (malloc(sizeof(WebRtc_Word16) * lengthIn * 2));
793 WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (WebRtc_Word32*)state1_);
794 lengthIn *= 2;
795 // 6:2
796 // We can only handle blocks of 480 samples
797 // Can be fixed, but I don't think it's needed
798 if ((lengthIn % 480) != 0)
799 {
800 free(tmp);
801 return -1;
802 }
803 tmp_mem = (WebRtc_Word32*)malloc(496 * sizeof(WebRtc_Word32));
804 for (int i = 0; i < lengthIn; i += 480)
805 {
806 WebRtcSpl_Resample48khzTo16khz(tmp + i, samplesOut + i / 3,
807 (WebRtcSpl_State48khzTo16khz *)state2_,
808 tmp_mem);
809 }
810 outLen = lengthIn / 3;
811 free(tmp);
812 free(tmp_mem);
813 return 0;
814 case kResamplerMode11To2:
815 // We can only handle blocks of 220 samples
816 // Can be fixed, but I don't think it's needed
817 if ((lengthIn % 220) != 0)
818 {
819 return -1;
820 }
821 if (maxLen < ((lengthIn * 2) / 11))
822 {
823 return -1;
824 }
825 tmp_mem = (WebRtc_Word32*)malloc(126 * sizeof(WebRtc_Word32));
826 tmp = (WebRtc_Word16*)malloc((lengthIn * 4) / 11 * sizeof(WebRtc_Word16));
827
828 for (int i = 0; i < lengthIn; i += 220)
829 {
830 WebRtcSpl_Resample22khzTo8khz(samplesIn + i, tmp + (i * 4) / 11,
831 (WebRtcSpl_State22khzTo8khz *)state1_,
832 tmp_mem);
833 }
834 lengthIn = (lengthIn * 4) / 11;
835
836 WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut, (WebRtc_Word32*)state2_);
837 outLen = lengthIn / 2;
838
839 free(tmp_mem);
840 free(tmp);
841 return 0;
842 case kResamplerMode11To4:
843 // We can only handle blocks of 220 samples
844 // Can be fixed, but I don't think it's needed
845 if ((lengthIn % 220) != 0)
846 {
847 return -1;
848 }
849 if (maxLen < ((lengthIn * 4) / 11))
850 {
851 return -1;
852 }
853 tmp_mem = (WebRtc_Word32*)malloc(126 * sizeof(WebRtc_Word32));
854
855 for (int i = 0; i < lengthIn; i += 220)
856 {
857 WebRtcSpl_Resample22khzTo8khz(samplesIn + i, samplesOut + (i * 4) / 11,
858 (WebRtcSpl_State22khzTo8khz *)state1_,
859 tmp_mem);
860 }
861 outLen = (lengthIn * 4) / 11;
862 free(tmp_mem);
863 return 0;
864 case kResamplerMode11To8:
865 // We can only handle blocks of 160 samples
866 // Can be fixed, but I don't think it's needed
867 if ((lengthIn % 220) != 0)
868 {
869 return -1;
870 }
871 if (maxLen < ((lengthIn * 8) / 11))
872 {
873 return -1;
874 }
875 tmp_mem = (WebRtc_Word32*)malloc(104 * sizeof(WebRtc_Word32));
876
877 for (int i = 0; i < lengthIn; i += 220)
878 {
879 WebRtcSpl_Resample22khzTo16khz(samplesIn + i, samplesOut + (i * 8) / 11,
880 (WebRtcSpl_State22khzTo16khz *)state1_,
881 tmp_mem);
882 }
883 outLen = (lengthIn * 8) / 11;
884 free(tmp_mem);
885 return 0;
886 break;
887
888 }
889 return 0;
890 }
891
892 // Asynchronous resampling, input
Insert(WebRtc_Word16 * samplesIn,int lengthIn)893 int Resampler::Insert(WebRtc_Word16 * samplesIn, int lengthIn)
894 {
895 if (my_type_ != kResamplerAsynchronous)
896 {
897 return -1;
898 }
899 int sizeNeeded, tenMsblock;
900
901 // Determine need for size of outBuffer
902 sizeNeeded = out_buffer_size_ + ((lengthIn + in_buffer_size_) * my_out_frequency_khz_)
903 / my_in_frequency_khz_;
904 if (sizeNeeded > out_buffer_size_max_)
905 {
906 // Round the value upwards to complete 10 ms blocks
907 tenMsblock = my_out_frequency_khz_ * 10;
908 sizeNeeded = (sizeNeeded / tenMsblock + 1) * tenMsblock;
909 out_buffer_ = (WebRtc_Word16*)realloc(out_buffer_, sizeNeeded * sizeof(WebRtc_Word16));
910 out_buffer_size_max_ = sizeNeeded;
911 }
912
913 // If we need to use inBuffer, make sure all input data fits there.
914
915 tenMsblock = my_in_frequency_khz_ * 10;
916 if (in_buffer_size_ || (lengthIn % tenMsblock))
917 {
918 // Check if input buffer size is enough
919 if ((in_buffer_size_ + lengthIn) > in_buffer_size_max_)
920 {
921 // Round the value upwards to complete 10 ms blocks
922 sizeNeeded = ((in_buffer_size_ + lengthIn) / tenMsblock + 1) * tenMsblock;
923 in_buffer_ = (WebRtc_Word16*)realloc(in_buffer_,
924 sizeNeeded * sizeof(WebRtc_Word16));
925 in_buffer_size_max_ = sizeNeeded;
926 }
927 // Copy in data to input buffer
928 memcpy(in_buffer_ + in_buffer_size_, samplesIn, lengthIn * sizeof(WebRtc_Word16));
929
930 // Resample all available 10 ms blocks
931 int lenOut;
932 int dataLenToResample = (in_buffer_size_ / tenMsblock) * tenMsblock;
933 Push(in_buffer_, dataLenToResample, out_buffer_ + out_buffer_size_,
934 out_buffer_size_max_ - out_buffer_size_, lenOut);
935 out_buffer_size_ += lenOut;
936
937 // Save the rest
938 memmove(in_buffer_, in_buffer_ + dataLenToResample,
939 (in_buffer_size_ - dataLenToResample) * sizeof(WebRtc_Word16));
940 in_buffer_size_ -= dataLenToResample;
941 } else
942 {
943 // Just resample
944 int lenOut;
945 Push(in_buffer_, lengthIn, out_buffer_ + out_buffer_size_,
946 out_buffer_size_max_ - out_buffer_size_, lenOut);
947 out_buffer_size_ += lenOut;
948 }
949
950 return 0;
951 }
952
953 // Asynchronous resampling output, remaining samples are buffered
Pull(WebRtc_Word16 * samplesOut,int desiredLen,int & outLen)954 int Resampler::Pull(WebRtc_Word16* samplesOut, int desiredLen, int &outLen)
955 {
956 if (my_type_ != kResamplerAsynchronous)
957 {
958 return -1;
959 }
960
961 // Check that we have enough data
962 if (desiredLen <= out_buffer_size_)
963 {
964 // Give out the date
965 memcpy(samplesOut, out_buffer_, desiredLen * sizeof(WebRtc_Word32));
966
967 // Shuffle down remaining
968 memmove(out_buffer_, out_buffer_ + desiredLen,
969 (out_buffer_size_ - desiredLen) * sizeof(WebRtc_Word16));
970
971 // Update remaining size
972 out_buffer_size_ -= desiredLen;
973
974 return 0;
975 } else
976 {
977 return -1;
978 }
979 }
980
981 } // namespace webrtc
982