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