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
22namespace webrtc {
23
24Resampler::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
42Resampler::Resampler(int inFreq, int outFreq, size_t num_channels)
43    : Resampler() {
44  Reset(inFreq, outFreq, num_channels);
45}
46
47Resampler::~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
79int 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
94int 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
404int 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