tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

resampler.cc (29000B)


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