Home | History | Annotate | Download | only in resampler
      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 
     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 
     42 Resampler::Resampler(int inFreq, int outFreq, size_t num_channels)
     43     : Resampler() {
     44   Reset(inFreq, outFreq, num_channels);
     45 }
     46 
     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 
     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 
     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
    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