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