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