diff options
Diffstat (limited to 'webrtc/common_audio/resampler/resampler.cc')
-rw-r--r-- | webrtc/common_audio/resampler/resampler.cc | 1755 |
1 files changed, 860 insertions, 895 deletions
diff --git a/webrtc/common_audio/resampler/resampler.cc b/webrtc/common_audio/resampler/resampler.cc index c9e7a1f..ccfed5a 100644 --- a/webrtc/common_audio/resampler/resampler.cc +++ b/webrtc/common_audio/resampler/resampler.cc @@ -8,16 +8,18 @@ * be found in the AUTHORS file in the root of the source tree. */ - /* * A wrapper for resampling a numerous amount of sampling combinations. */ +#include "common_audio/resampler/include/resampler.h" + +#include <stdint.h> #include <stdlib.h> #include <string.h> -#include "webrtc/common_audio/resampler/include/resampler.h" -#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" +#include "common_audio/signal_processing/include/signal_processing_library.h" +#include "rtc_base/logging.h" namespace webrtc { @@ -35,925 +37,888 @@ Resampler::Resampler() my_out_frequency_khz_(0), my_mode_(kResamplerMode1To1), num_channels_(0), - slave_left_(nullptr), - slave_right_(nullptr) { -} + helper_left_(nullptr), + helper_right_(nullptr) {} -Resampler::Resampler(int inFreq, int outFreq, int num_channels) +Resampler::Resampler(int inFreq, int outFreq, size_t num_channels) : Resampler() { Reset(inFreq, outFreq, num_channels); } -Resampler::~Resampler() -{ - if (state1_) - { - free(state1_); - } - if (state2_) - { - free(state2_); - } - if (state3_) - { - free(state3_); - } - if (in_buffer_) - { - free(in_buffer_); - } - if (out_buffer_) - { - free(out_buffer_); - } - if (slave_left_) - { - delete slave_left_; - } - if (slave_right_) - { - delete slave_right_; - } +Resampler::~Resampler() { + if (state1_) { + free(state1_); + } + if (state2_) { + free(state2_); + } + if (state3_) { + free(state3_); + } + if (in_buffer_) { + free(in_buffer_); + } + if (out_buffer_) { + free(out_buffer_); + } + if (helper_left_) { + delete helper_left_; + } + if (helper_right_) { + delete helper_right_; + } } -int Resampler::ResetIfNeeded(int inFreq, int outFreq, int num_channels) -{ - int tmpInFreq_kHz = inFreq / 1000; - int tmpOutFreq_kHz = outFreq / 1000; - - if ((tmpInFreq_kHz != my_in_frequency_khz_) || (tmpOutFreq_kHz != my_out_frequency_khz_) - || (num_channels != num_channels_)) - { - return Reset(inFreq, outFreq, num_channels); - } else - { - return 0; - } +int Resampler::ResetIfNeeded(int inFreq, int outFreq, size_t num_channels) { + int tmpInFreq_kHz = inFreq / 1000; + int tmpOutFreq_kHz = outFreq / 1000; + + if ((tmpInFreq_kHz != my_in_frequency_khz_) || + (tmpOutFreq_kHz != my_out_frequency_khz_) || + (num_channels != num_channels_)) { + return Reset(inFreq, outFreq, num_channels); + } else { + return 0; + } } -int Resampler::Reset(int inFreq, int outFreq, int num_channels) -{ - if (num_channels != 1 && num_channels != 2) { - return -1; - } - num_channels_ = num_channels; +int Resampler::Reset(int inFreq, int outFreq, size_t num_channels) { + if (num_channels != 1 && num_channels != 2) { + RTC_LOG(LS_WARNING) + << "Reset() called with unsupported channel count, num_channels = " + << num_channels; + return -1; + } + ResamplerMode mode; + if (ComputeResamplerMode(inFreq, outFreq, &mode) != 0) { + RTC_LOG(LS_WARNING) + << "Reset() called with unsupported sample rates, inFreq = " << inFreq + << ", outFreq = " << outFreq; + return -1; + } + // Reinitialize internal state for the frequencies and sample rates. + num_channels_ = num_channels; + my_mode_ = mode; + + if (state1_) { + free(state1_); + state1_ = nullptr; + } + if (state2_) { + free(state2_); + state2_ = nullptr; + } + if (state3_) { + free(state3_); + state3_ = nullptr; + } + if (in_buffer_) { + free(in_buffer_); + in_buffer_ = nullptr; + } + if (out_buffer_) { + free(out_buffer_); + out_buffer_ = nullptr; + } + if (helper_left_) { + delete helper_left_; + helper_left_ = nullptr; + } + if (helper_right_) { + delete helper_right_; + helper_right_ = nullptr; + } + + in_buffer_size_ = 0; + out_buffer_size_ = 0; + in_buffer_size_max_ = 0; + out_buffer_size_max_ = 0; + + // We need to track what domain we're in. + my_in_frequency_khz_ = inFreq / 1000; + my_out_frequency_khz_ = outFreq / 1000; + + if (num_channels_ == 2) { + // Create two mono resamplers. + helper_left_ = new Resampler(inFreq, outFreq, 1); + helper_right_ = new Resampler(inFreq, outFreq, 1); + } + + // Now create the states we need. + switch (my_mode_) { + case kResamplerMode1To1: + // No state needed; + break; + case kResamplerMode1To2: + state1_ = malloc(8 * sizeof(int32_t)); + memset(state1_, 0, 8 * sizeof(int32_t)); + break; + case kResamplerMode1To3: + state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz)); + WebRtcSpl_ResetResample16khzTo48khz( + static_cast<WebRtcSpl_State16khzTo48khz*>(state1_)); + break; + case kResamplerMode1To4: + // 1:2 + state1_ = malloc(8 * sizeof(int32_t)); + memset(state1_, 0, 8 * sizeof(int32_t)); + // 2:4 + state2_ = malloc(8 * sizeof(int32_t)); + memset(state2_, 0, 8 * sizeof(int32_t)); + break; + case kResamplerMode1To6: + // 1:2 + state1_ = malloc(8 * sizeof(int32_t)); + memset(state1_, 0, 8 * sizeof(int32_t)); + // 2:6 + state2_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz)); + WebRtcSpl_ResetResample16khzTo48khz( + static_cast<WebRtcSpl_State16khzTo48khz*>(state2_)); + break; + case kResamplerMode1To12: + // 1:2 + state1_ = malloc(8 * sizeof(int32_t)); + memset(state1_, 0, 8 * sizeof(int32_t)); + // 2:4 + state2_ = malloc(8 * sizeof(int32_t)); + memset(state2_, 0, 8 * sizeof(int32_t)); + // 4:12 + state3_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz)); + WebRtcSpl_ResetResample16khzTo48khz( + static_cast<WebRtcSpl_State16khzTo48khz*>(state3_)); + break; + case kResamplerMode2To3: + // 2:6 + state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz)); + WebRtcSpl_ResetResample16khzTo48khz( + static_cast<WebRtcSpl_State16khzTo48khz*>(state1_)); + // 6:3 + state2_ = malloc(8 * sizeof(int32_t)); + memset(state2_, 0, 8 * sizeof(int32_t)); + break; + case kResamplerMode2To11: + state1_ = malloc(8 * sizeof(int32_t)); + memset(state1_, 0, 8 * sizeof(int32_t)); + + state2_ = malloc(sizeof(WebRtcSpl_State8khzTo22khz)); + WebRtcSpl_ResetResample8khzTo22khz( + static_cast<WebRtcSpl_State8khzTo22khz*>(state2_)); + break; + case kResamplerMode4To11: + state1_ = malloc(sizeof(WebRtcSpl_State8khzTo22khz)); + WebRtcSpl_ResetResample8khzTo22khz( + static_cast<WebRtcSpl_State8khzTo22khz*>(state1_)); + break; + case kResamplerMode8To11: + state1_ = malloc(sizeof(WebRtcSpl_State16khzTo22khz)); + WebRtcSpl_ResetResample16khzTo22khz( + static_cast<WebRtcSpl_State16khzTo22khz*>(state1_)); + break; + case kResamplerMode11To16: + state1_ = malloc(8 * sizeof(int32_t)); + memset(state1_, 0, 8 * sizeof(int32_t)); + + state2_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz)); + WebRtcSpl_ResetResample22khzTo16khz( + static_cast<WebRtcSpl_State22khzTo16khz*>(state2_)); + break; + case kResamplerMode11To32: + // 11 -> 22 + state1_ = malloc(8 * sizeof(int32_t)); + memset(state1_, 0, 8 * sizeof(int32_t)); + + // 22 -> 16 + state2_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz)); + WebRtcSpl_ResetResample22khzTo16khz( + static_cast<WebRtcSpl_State22khzTo16khz*>(state2_)); + + // 16 -> 32 + state3_ = malloc(8 * sizeof(int32_t)); + memset(state3_, 0, 8 * sizeof(int32_t)); + + break; + case kResamplerMode2To1: + state1_ = malloc(8 * sizeof(int32_t)); + memset(state1_, 0, 8 * sizeof(int32_t)); + break; + case kResamplerMode3To1: + state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz)); + WebRtcSpl_ResetResample48khzTo16khz( + static_cast<WebRtcSpl_State48khzTo16khz*>(state1_)); + break; + case kResamplerMode4To1: + // 4:2 + state1_ = malloc(8 * sizeof(int32_t)); + memset(state1_, 0, 8 * sizeof(int32_t)); + // 2:1 + state2_ = malloc(8 * sizeof(int32_t)); + memset(state2_, 0, 8 * sizeof(int32_t)); + break; + case kResamplerMode6To1: + // 6:2 + state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz)); + WebRtcSpl_ResetResample48khzTo16khz( + static_cast<WebRtcSpl_State48khzTo16khz*>(state1_)); + // 2:1 + state2_ = malloc(8 * sizeof(int32_t)); + memset(state2_, 0, 8 * sizeof(int32_t)); + break; + case kResamplerMode12To1: + // 12:4 + state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz)); + WebRtcSpl_ResetResample48khzTo16khz( + static_cast<WebRtcSpl_State48khzTo16khz*>(state1_)); + // 4:2 + state2_ = malloc(8 * sizeof(int32_t)); + memset(state2_, 0, 8 * sizeof(int32_t)); + // 2:1 + state3_ = malloc(8 * sizeof(int32_t)); + memset(state3_, 0, 8 * sizeof(int32_t)); + break; + case kResamplerMode3To2: + // 3:6 + state1_ = malloc(8 * sizeof(int32_t)); + memset(state1_, 0, 8 * sizeof(int32_t)); + // 6:2 + state2_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz)); + WebRtcSpl_ResetResample48khzTo16khz( + static_cast<WebRtcSpl_State48khzTo16khz*>(state2_)); + break; + case kResamplerMode11To2: + state1_ = malloc(sizeof(WebRtcSpl_State22khzTo8khz)); + WebRtcSpl_ResetResample22khzTo8khz( + static_cast<WebRtcSpl_State22khzTo8khz*>(state1_)); + + state2_ = malloc(8 * sizeof(int32_t)); + memset(state2_, 0, 8 * sizeof(int32_t)); + + break; + case kResamplerMode11To4: + state1_ = malloc(sizeof(WebRtcSpl_State22khzTo8khz)); + WebRtcSpl_ResetResample22khzTo8khz( + static_cast<WebRtcSpl_State22khzTo8khz*>(state1_)); + break; + case kResamplerMode11To8: + state1_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz)); + WebRtcSpl_ResetResample22khzTo16khz( + static_cast<WebRtcSpl_State22khzTo16khz*>(state1_)); + break; + } + + return 0; +} - if (state1_) - { - free(state1_); - state1_ = NULL; - } - if (state2_) - { - free(state2_); - state2_ = NULL; - } - if (state3_) - { - free(state3_); - state3_ = NULL; - } - if (in_buffer_) - { - free(in_buffer_); - in_buffer_ = NULL; +int Resampler::ComputeResamplerMode(int in_freq_hz, + int out_freq_hz, + ResamplerMode* mode) { + // Start with a math exercise, Euclid's algorithm to find the gcd: + int a = in_freq_hz; + int b = out_freq_hz; + int c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + // b is now the gcd; + + // Scale with GCD + const int reduced_in_freq = in_freq_hz / b; + const int reduced_out_freq = out_freq_hz / b; + + if (reduced_in_freq == reduced_out_freq) { + *mode = kResamplerMode1To1; + } else if (reduced_in_freq == 1) { + switch (reduced_out_freq) { + case 2: + *mode = kResamplerMode1To2; + break; + case 3: + *mode = kResamplerMode1To3; + break; + case 4: + *mode = kResamplerMode1To4; + break; + case 6: + *mode = kResamplerMode1To6; + break; + case 12: + *mode = kResamplerMode1To12; + break; + default: + return -1; } - if (out_buffer_) - { - free(out_buffer_); - out_buffer_ = NULL; + } else if (reduced_out_freq == 1) { + switch (reduced_in_freq) { + case 2: + *mode = kResamplerMode2To1; + break; + case 3: + *mode = kResamplerMode3To1; + break; + case 4: + *mode = kResamplerMode4To1; + break; + case 6: + *mode = kResamplerMode6To1; + break; + case 12: + *mode = kResamplerMode12To1; + break; + default: + return -1; } - if (slave_left_) - { - delete slave_left_; - slave_left_ = NULL; + } else if ((reduced_in_freq == 2) && (reduced_out_freq == 3)) { + *mode = kResamplerMode2To3; + } else if ((reduced_in_freq == 2) && (reduced_out_freq == 11)) { + *mode = kResamplerMode2To11; + } else if ((reduced_in_freq == 4) && (reduced_out_freq == 11)) { + *mode = kResamplerMode4To11; + } else if ((reduced_in_freq == 8) && (reduced_out_freq == 11)) { + *mode = kResamplerMode8To11; + } else if ((reduced_in_freq == 3) && (reduced_out_freq == 2)) { + *mode = kResamplerMode3To2; + } else if ((reduced_in_freq == 11) && (reduced_out_freq == 2)) { + *mode = kResamplerMode11To2; + } else if ((reduced_in_freq == 11) && (reduced_out_freq == 4)) { + *mode = kResamplerMode11To4; + } else if ((reduced_in_freq == 11) && (reduced_out_freq == 16)) { + *mode = kResamplerMode11To16; + } else if ((reduced_in_freq == 11) && (reduced_out_freq == 32)) { + *mode = kResamplerMode11To32; + } else if ((reduced_in_freq == 11) && (reduced_out_freq == 8)) { + *mode = kResamplerMode11To8; + } else { + return -1; + } + return 0; +} + +// Synchronous resampling, all output samples are written to samplesOut +int Resampler::Push(const int16_t* samplesIn, + size_t lengthIn, + int16_t* samplesOut, + size_t maxLen, + size_t& outLen) { + if (num_channels_ == 2) { + // Split up the signal and call the helper object for each channel + int16_t* left = + static_cast<int16_t*>(malloc(lengthIn * sizeof(int16_t) / 2)); + int16_t* right = + static_cast<int16_t*>(malloc(lengthIn * sizeof(int16_t) / 2)); + int16_t* out_left = + static_cast<int16_t*>(malloc(maxLen / 2 * sizeof(int16_t))); + int16_t* out_right = + static_cast<int16_t*>(malloc(maxLen / 2 * sizeof(int16_t))); + int res = 0; + for (size_t i = 0; i < lengthIn; i += 2) { + left[i >> 1] = samplesIn[i]; + right[i >> 1] = samplesIn[i + 1]; } - if (slave_right_) - { - delete slave_right_; - slave_right_ = NULL; + + // It's OK to overwrite the local parameter, since it's just a copy + lengthIn = lengthIn / 2; + + size_t actualOutLen_left = 0; + size_t actualOutLen_right = 0; + // Do resampling for right channel + res |= helper_left_->Push(left, lengthIn, out_left, maxLen / 2, + actualOutLen_left); + res |= helper_right_->Push(right, lengthIn, out_right, maxLen / 2, + actualOutLen_right); + if (res || (actualOutLen_left != actualOutLen_right)) { + free(left); + free(right); + free(out_left); + free(out_right); + return -1; } - in_buffer_size_ = 0; - out_buffer_size_ = 0; - in_buffer_size_max_ = 0; - out_buffer_size_max_ = 0; - - // Start with a math exercise, Euclid's algorithm to find the gcd: - int a = inFreq; - int b = outFreq; - int c = a % b; - while (c != 0) - { - a = b; - b = c; - c = a % b; + // Reassemble the signal + for (size_t i = 0; i < actualOutLen_left; i++) { + samplesOut[i * 2] = out_left[i]; + samplesOut[i * 2 + 1] = out_right[i]; } - // b is now the gcd; + outLen = 2 * actualOutLen_left; - // We need to track what domain we're in. - my_in_frequency_khz_ = inFreq / 1000; - my_out_frequency_khz_ = outFreq / 1000; + free(left); + free(right); + free(out_left); + free(out_right); - // Scale with GCD - inFreq = inFreq / b; - outFreq = outFreq / b; + return 0; + } + + // Containers for temp samples + int16_t* tmp; + int16_t* tmp_2; + // tmp data for resampling routines + int32_t* tmp_mem; + + switch (my_mode_) { + case kResamplerMode1To1: + memcpy(samplesOut, samplesIn, lengthIn * sizeof(int16_t)); + outLen = lengthIn; + break; + case kResamplerMode1To2: + if (maxLen < (lengthIn * 2)) { + return -1; + } + WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, + static_cast<int32_t*>(state1_)); + outLen = lengthIn * 2; + return 0; + case kResamplerMode1To3: + + // We can only handle blocks of 160 samples + // Can be fixed, but I don't think it's needed + if ((lengthIn % 160) != 0) { + return -1; + } + if (maxLen < (lengthIn * 3)) { + return -1; + } + tmp_mem = static_cast<int32_t*>(malloc(336 * sizeof(int32_t))); + + for (size_t i = 0; i < lengthIn; i += 160) { + WebRtcSpl_Resample16khzTo48khz( + samplesIn + i, samplesOut + i * 3, + static_cast<WebRtcSpl_State16khzTo48khz*>(state1_), tmp_mem); + } + outLen = lengthIn * 3; + free(tmp_mem); + return 0; + case kResamplerMode1To4: + if (maxLen < (lengthIn * 4)) { + return -1; + } + + tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * 2 * lengthIn)); + // 1:2 + WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, + static_cast<int32_t*>(state1_)); + // 2:4 + WebRtcSpl_UpsampleBy2(tmp, lengthIn * 2, samplesOut, + static_cast<int32_t*>(state2_)); + outLen = lengthIn * 4; + free(tmp); + return 0; + case kResamplerMode1To6: + // We can only handle blocks of 80 samples + // Can be fixed, but I don't think it's needed + if ((lengthIn % 80) != 0) { + return -1; + } + if (maxLen < (lengthIn * 6)) { + return -1; + } + + // 1:2 + + tmp_mem = static_cast<int32_t*>(malloc(336 * sizeof(int32_t))); + tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * 2 * lengthIn)); + + WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, + static_cast<int32_t*>(state1_)); + outLen = lengthIn * 2; + + for (size_t i = 0; i < outLen; i += 160) { + WebRtcSpl_Resample16khzTo48khz( + tmp + i, samplesOut + i * 3, + static_cast<WebRtcSpl_State16khzTo48khz*>(state2_), tmp_mem); + } + outLen = outLen * 3; + free(tmp_mem); + free(tmp); + + return 0; + case kResamplerMode1To12: + // We can only handle blocks of 40 samples + // Can be fixed, but I don't think it's needed + if ((lengthIn % 40) != 0) { + return -1; + } + if (maxLen < (lengthIn * 12)) { + return -1; + } + + tmp_mem = static_cast<int32_t*>(malloc(336 * sizeof(int32_t))); + tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * 4 * lengthIn)); + // 1:2 + WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, + static_cast<int32_t*>(state1_)); + outLen = lengthIn * 2; + // 2:4 + WebRtcSpl_UpsampleBy2(samplesOut, outLen, tmp, + static_cast<int32_t*>(state2_)); + outLen = outLen * 2; + // 4:12 + for (size_t i = 0; i < outLen; i += 160) { + // WebRtcSpl_Resample16khzTo48khz() takes a block of 160 samples + // as input and outputs a resampled block of 480 samples. The + // data is now actually in 32 kHz sampling rate, despite the + // function name, and with a resampling factor of three becomes + // 96 kHz. + WebRtcSpl_Resample16khzTo48khz( + tmp + i, samplesOut + i * 3, + static_cast<WebRtcSpl_State16khzTo48khz*>(state3_), tmp_mem); + } + outLen = outLen * 3; + free(tmp_mem); + free(tmp); + + return 0; + case kResamplerMode2To3: + if (maxLen < (lengthIn * 3 / 2)) { + return -1; + } + // 2:6 + // We can only handle blocks of 160 samples + // Can be fixed, but I don't think it's needed + if ((lengthIn % 160) != 0) { + return -1; + } + tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * lengthIn * 3)); + tmp_mem = static_cast<int32_t*>(malloc(336 * sizeof(int32_t))); + for (size_t i = 0; i < lengthIn; i += 160) { + WebRtcSpl_Resample16khzTo48khz( + samplesIn + i, tmp + i * 3, + static_cast<WebRtcSpl_State16khzTo48khz*>(state1_), tmp_mem); + } + lengthIn = lengthIn * 3; + // 6:3 + WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut, + static_cast<int32_t*>(state2_)); + outLen = lengthIn / 2; + free(tmp); + free(tmp_mem); + return 0; + case kResamplerMode2To11: + + // We can only handle blocks of 80 samples + // Can be fixed, but I don't think it's needed + if ((lengthIn % 80) != 0) { + return -1; + } + if (maxLen < ((lengthIn * 11) / 2)) { + return -1; + } + tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * 2 * lengthIn)); + // 1:2 + WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, + static_cast<int32_t*>(state1_)); + lengthIn *= 2; + + tmp_mem = static_cast<int32_t*>(malloc(98 * sizeof(int32_t))); + + for (size_t i = 0; i < lengthIn; i += 80) { + WebRtcSpl_Resample8khzTo22khz( + tmp + i, samplesOut + (i * 11) / 4, + static_cast<WebRtcSpl_State8khzTo22khz*>(state2_), tmp_mem); + } + outLen = (lengthIn * 11) / 4; + free(tmp_mem); + free(tmp); + return 0; + case kResamplerMode4To11: + + // We can only handle blocks of 80 samples + // Can be fixed, but I don't think it's needed + if ((lengthIn % 80) != 0) { + return -1; + } + if (maxLen < ((lengthIn * 11) / 4)) { + return -1; + } + tmp_mem = static_cast<int32_t*>(malloc(98 * sizeof(int32_t))); + + for (size_t i = 0; i < lengthIn; i += 80) { + WebRtcSpl_Resample8khzTo22khz( + samplesIn + i, samplesOut + (i * 11) / 4, + static_cast<WebRtcSpl_State8khzTo22khz*>(state1_), tmp_mem); + } + outLen = (lengthIn * 11) / 4; + free(tmp_mem); + return 0; + case kResamplerMode8To11: + // We can only handle blocks of 160 samples + // Can be fixed, but I don't think it's needed + if ((lengthIn % 160) != 0) { + return -1; + } + if (maxLen < ((lengthIn * 11) / 8)) { + return -1; + } + tmp_mem = static_cast<int32_t*>(malloc(88 * sizeof(int32_t))); + + for (size_t i = 0; i < lengthIn; i += 160) { + WebRtcSpl_Resample16khzTo22khz( + samplesIn + i, samplesOut + (i * 11) / 8, + static_cast<WebRtcSpl_State16khzTo22khz*>(state1_), tmp_mem); + } + outLen = (lengthIn * 11) / 8; + free(tmp_mem); + return 0; + + case kResamplerMode11To16: + // We can only handle blocks of 110 samples + if ((lengthIn % 110) != 0) { + return -1; + } + if (maxLen < ((lengthIn * 16) / 11)) { + return -1; + } - if (num_channels_ == 2) - { - // Create two mono resamplers. - slave_left_ = new Resampler(inFreq, outFreq, 1); - slave_right_ = new Resampler(inFreq, outFreq, 1); - } + tmp_mem = static_cast<int32_t*>(malloc(104 * sizeof(int32_t))); + tmp = static_cast<int16_t*>(malloc((sizeof(int16_t) * lengthIn * 2))); + + WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, + static_cast<int32_t*>(state1_)); + + for (size_t i = 0; i < (lengthIn * 2); i += 220) { + WebRtcSpl_Resample22khzTo16khz( + tmp + i, samplesOut + (i / 220) * 160, + static_cast<WebRtcSpl_State22khzTo16khz*>(state2_), tmp_mem); + } + + outLen = (lengthIn * 16) / 11; - if (inFreq == outFreq) - { - my_mode_ = kResamplerMode1To1; - } else if (inFreq == 1) - { - switch (outFreq) - { - case 2: - my_mode_ = kResamplerMode1To2; - break; - case 3: - my_mode_ = kResamplerMode1To3; - break; - case 4: - my_mode_ = kResamplerMode1To4; - break; - case 6: - my_mode_ = kResamplerMode1To6; - break; - case 12: - my_mode_ = kResamplerMode1To12; - break; - default: - return -1; - } - } else if (outFreq == 1) - { - switch (inFreq) - { - case 2: - my_mode_ = kResamplerMode2To1; - break; - case 3: - my_mode_ = kResamplerMode3To1; - break; - case 4: - my_mode_ = kResamplerMode4To1; - break; - case 6: - my_mode_ = kResamplerMode6To1; - break; - case 12: - my_mode_ = kResamplerMode12To1; - break; - default: - return -1; - } - } else if ((inFreq == 2) && (outFreq == 3)) - { - my_mode_ = kResamplerMode2To3; - } else if ((inFreq == 2) && (outFreq == 11)) - { - my_mode_ = kResamplerMode2To11; - } else if ((inFreq == 4) && (outFreq == 11)) - { - my_mode_ = kResamplerMode4To11; - } else if ((inFreq == 8) && (outFreq == 11)) - { - my_mode_ = kResamplerMode8To11; - } else if ((inFreq == 3) && (outFreq == 2)) - { - my_mode_ = kResamplerMode3To2; - } else if ((inFreq == 11) && (outFreq == 2)) - { - my_mode_ = kResamplerMode11To2; - } else if ((inFreq == 11) && (outFreq == 4)) - { - my_mode_ = kResamplerMode11To4; - } else if ((inFreq == 11) && (outFreq == 16)) - { - my_mode_ = kResamplerMode11To16; - } else if ((inFreq == 11) && (outFreq == 32)) - { - my_mode_ = kResamplerMode11To32; - } else if ((inFreq == 11) && (outFreq == 8)) - { - my_mode_ = kResamplerMode11To8; - } else - { + free(tmp_mem); + free(tmp); + return 0; + + case kResamplerMode11To32: + + // We can only handle blocks of 110 samples + if ((lengthIn % 110) != 0) { return -1; - } + } + if (maxLen < ((lengthIn * 32) / 11)) { + return -1; + } - // Now create the states we need - switch (my_mode_) - { - case kResamplerMode1To1: - // No state needed; - break; - case kResamplerMode1To2: - state1_ = malloc(8 * sizeof(int32_t)); - memset(state1_, 0, 8 * sizeof(int32_t)); - break; - case kResamplerMode1To3: - state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz)); - WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state1_); - break; - case kResamplerMode1To4: - // 1:2 - state1_ = malloc(8 * sizeof(int32_t)); - memset(state1_, 0, 8 * sizeof(int32_t)); - // 2:4 - state2_ = malloc(8 * sizeof(int32_t)); - memset(state2_, 0, 8 * sizeof(int32_t)); - break; - case kResamplerMode1To6: - // 1:2 - state1_ = malloc(8 * sizeof(int32_t)); - memset(state1_, 0, 8 * sizeof(int32_t)); - // 2:6 - state2_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz)); - WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state2_); - break; - case kResamplerMode1To12: - // 1:2 - state1_ = malloc(8 * sizeof(int32_t)); - memset(state1_, 0, 8 * sizeof(int32_t)); - // 2:4 - state2_ = malloc(8 * sizeof(int32_t)); - memset(state2_, 0, 8 * sizeof(int32_t)); - // 4:12 - state3_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz)); - WebRtcSpl_ResetResample16khzTo48khz( - (WebRtcSpl_State16khzTo48khz*) state3_); - break; - case kResamplerMode2To3: - // 2:6 - state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz)); - WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state1_); - // 6:3 - state2_ = malloc(8 * sizeof(int32_t)); - memset(state2_, 0, 8 * sizeof(int32_t)); - break; - case kResamplerMode2To11: - state1_ = malloc(8 * sizeof(int32_t)); - memset(state1_, 0, 8 * sizeof(int32_t)); - - state2_ = malloc(sizeof(WebRtcSpl_State8khzTo22khz)); - WebRtcSpl_ResetResample8khzTo22khz((WebRtcSpl_State8khzTo22khz *)state2_); - break; - case kResamplerMode4To11: - state1_ = malloc(sizeof(WebRtcSpl_State8khzTo22khz)); - WebRtcSpl_ResetResample8khzTo22khz((WebRtcSpl_State8khzTo22khz *)state1_); - break; - case kResamplerMode8To11: - state1_ = malloc(sizeof(WebRtcSpl_State16khzTo22khz)); - WebRtcSpl_ResetResample16khzTo22khz((WebRtcSpl_State16khzTo22khz *)state1_); - break; - case kResamplerMode11To16: - state1_ = malloc(8 * sizeof(int32_t)); - memset(state1_, 0, 8 * sizeof(int32_t)); - - state2_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz)); - WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state2_); - break; - case kResamplerMode11To32: - // 11 -> 22 - state1_ = malloc(8 * sizeof(int32_t)); - memset(state1_, 0, 8 * sizeof(int32_t)); - - // 22 -> 16 - state2_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz)); - WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state2_); - - // 16 -> 32 - state3_ = malloc(8 * sizeof(int32_t)); - memset(state3_, 0, 8 * sizeof(int32_t)); - - break; - case kResamplerMode2To1: - state1_ = malloc(8 * sizeof(int32_t)); - memset(state1_, 0, 8 * sizeof(int32_t)); - break; - case kResamplerMode3To1: - state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz)); - WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state1_); - break; - case kResamplerMode4To1: - // 4:2 - state1_ = malloc(8 * sizeof(int32_t)); - memset(state1_, 0, 8 * sizeof(int32_t)); - // 2:1 - state2_ = malloc(8 * sizeof(int32_t)); - memset(state2_, 0, 8 * sizeof(int32_t)); - break; - case kResamplerMode6To1: - // 6:2 - state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz)); - WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state1_); - // 2:1 - state2_ = malloc(8 * sizeof(int32_t)); - memset(state2_, 0, 8 * sizeof(int32_t)); - break; - case kResamplerMode12To1: - // 12:4 - state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz)); - WebRtcSpl_ResetResample48khzTo16khz( - (WebRtcSpl_State48khzTo16khz*) state1_); - // 4:2 - state2_ = malloc(8 * sizeof(int32_t)); - memset(state2_, 0, 8 * sizeof(int32_t)); - // 2:1 - state3_ = malloc(8 * sizeof(int32_t)); - memset(state3_, 0, 8 * sizeof(int32_t)); - break; - case kResamplerMode3To2: - // 3:6 - state1_ = malloc(8 * sizeof(int32_t)); - memset(state1_, 0, 8 * sizeof(int32_t)); - // 6:2 - state2_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz)); - WebRtcSpl_ResetResample48khzTo16khz((WebRtcSpl_State48khzTo16khz *)state2_); - break; - case kResamplerMode11To2: - state1_ = malloc(sizeof(WebRtcSpl_State22khzTo8khz)); - WebRtcSpl_ResetResample22khzTo8khz((WebRtcSpl_State22khzTo8khz *)state1_); - - state2_ = malloc(8 * sizeof(int32_t)); - memset(state2_, 0, 8 * sizeof(int32_t)); - - break; - case kResamplerMode11To4: - state1_ = malloc(sizeof(WebRtcSpl_State22khzTo8khz)); - WebRtcSpl_ResetResample22khzTo8khz((WebRtcSpl_State22khzTo8khz *)state1_); - break; - case kResamplerMode11To8: - state1_ = malloc(sizeof(WebRtcSpl_State22khzTo16khz)); - WebRtcSpl_ResetResample22khzTo16khz((WebRtcSpl_State22khzTo16khz *)state1_); - break; + tmp_mem = static_cast<int32_t*>(malloc(104 * sizeof(int32_t))); + tmp = static_cast<int16_t*>(malloc((sizeof(int16_t) * lengthIn * 2))); - } + // 11 -> 22 kHz in samplesOut + WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, + static_cast<int32_t*>(state1_)); - return 0; -} + // 22 -> 16 in tmp + for (size_t i = 0; i < (lengthIn * 2); i += 220) { + WebRtcSpl_Resample22khzTo16khz( + samplesOut + i, tmp + (i / 220) * 160, + static_cast<WebRtcSpl_State22khzTo16khz*>(state2_), tmp_mem); + } -// Synchronous resampling, all output samples are written to samplesOut -int Resampler::Push(const int16_t * samplesIn, size_t lengthIn, - int16_t* samplesOut, size_t maxLen, size_t &outLen) -{ - if (num_channels_ == 2) - { - // Split up the signal and call the slave object for each channel - int16_t* left = (int16_t*)malloc(lengthIn * sizeof(int16_t) / 2); - int16_t* right = (int16_t*)malloc(lengthIn * sizeof(int16_t) / 2); - int16_t* out_left = (int16_t*)malloc(maxLen / 2 * sizeof(int16_t)); - int16_t* out_right = - (int16_t*)malloc(maxLen / 2 * sizeof(int16_t)); - int res = 0; - for (size_t i = 0; i < lengthIn; i += 2) - { - left[i >> 1] = samplesIn[i]; - right[i >> 1] = samplesIn[i + 1]; - } - - // It's OK to overwrite the local parameter, since it's just a copy - lengthIn = lengthIn / 2; - - size_t actualOutLen_left = 0; - size_t actualOutLen_right = 0; - // Do resampling for right channel - res |= slave_left_->Push(left, lengthIn, out_left, maxLen / 2, actualOutLen_left); - res |= slave_right_->Push(right, lengthIn, out_right, maxLen / 2, actualOutLen_right); - if (res || (actualOutLen_left != actualOutLen_right)) - { - free(left); - free(right); - free(out_left); - free(out_right); - return -1; - } - - // Reassemble the signal - for (size_t i = 0; i < actualOutLen_left; i++) - { - samplesOut[i * 2] = out_left[i]; - samplesOut[i * 2 + 1] = out_right[i]; - } - outLen = 2 * actualOutLen_left; - - free(left); - free(right); - free(out_left); - free(out_right); - - return 0; - } + // 16 -> 32 in samplesOut + WebRtcSpl_UpsampleBy2(tmp, (lengthIn * 16) / 11, samplesOut, + static_cast<int32_t*>(state3_)); - // Containers for temp samples - int16_t* tmp; - int16_t* tmp_2; - // tmp data for resampling routines - int32_t* tmp_mem; - - switch (my_mode_) - { - case kResamplerMode1To1: - memcpy(samplesOut, samplesIn, lengthIn * sizeof(int16_t)); - outLen = lengthIn; - break; - case kResamplerMode1To2: - if (maxLen < (lengthIn * 2)) - { - return -1; - } - WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, (int32_t*)state1_); - outLen = lengthIn * 2; - return 0; - case kResamplerMode1To3: - - // We can only handle blocks of 160 samples - // Can be fixed, but I don't think it's needed - if ((lengthIn % 160) != 0) - { - return -1; - } - if (maxLen < (lengthIn * 3)) - { - return -1; - } - tmp_mem = (int32_t*)malloc(336 * sizeof(int32_t)); - - for (size_t i = 0; i < lengthIn; i += 160) - { - WebRtcSpl_Resample16khzTo48khz(samplesIn + i, samplesOut + i * 3, - (WebRtcSpl_State16khzTo48khz *)state1_, - tmp_mem); - } - outLen = lengthIn * 3; - free(tmp_mem); - return 0; - case kResamplerMode1To4: - if (maxLen < (lengthIn * 4)) - { - return -1; - } - - tmp = (int16_t*)malloc(sizeof(int16_t) * 2 * lengthIn); - // 1:2 - WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (int32_t*)state1_); - // 2:4 - WebRtcSpl_UpsampleBy2(tmp, lengthIn * 2, samplesOut, (int32_t*)state2_); - outLen = lengthIn * 4; - free(tmp); - return 0; - case kResamplerMode1To6: - // We can only handle blocks of 80 samples - // Can be fixed, but I don't think it's needed - if ((lengthIn % 80) != 0) - { - return -1; - } - if (maxLen < (lengthIn * 6)) - { - return -1; - } - - //1:2 - - tmp_mem = (int32_t*)malloc(336 * sizeof(int32_t)); - tmp = (int16_t*)malloc(sizeof(int16_t) * 2 * lengthIn); - - WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (int32_t*)state1_); - outLen = lengthIn * 2; - - for (size_t i = 0; i < outLen; i += 160) - { - WebRtcSpl_Resample16khzTo48khz(tmp + i, samplesOut + i * 3, - (WebRtcSpl_State16khzTo48khz *)state2_, - tmp_mem); - } - outLen = outLen * 3; - free(tmp_mem); - free(tmp); - - return 0; - case kResamplerMode1To12: - // We can only handle blocks of 40 samples - // Can be fixed, but I don't think it's needed - if ((lengthIn % 40) != 0) { - return -1; - } - if (maxLen < (lengthIn * 12)) { - return -1; - } - - tmp_mem = (int32_t*) malloc(336 * sizeof(int32_t)); - tmp = (int16_t*) malloc(sizeof(int16_t) * 4 * lengthIn); - //1:2 - WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, - (int32_t*) state1_); - outLen = lengthIn * 2; - //2:4 - WebRtcSpl_UpsampleBy2(samplesOut, outLen, tmp, (int32_t*) state2_); - outLen = outLen * 2; - // 4:12 - for (size_t i = 0; i < outLen; i += 160) { - // WebRtcSpl_Resample16khzTo48khz() takes a block of 160 samples - // as input and outputs a resampled block of 480 samples. The - // data is now actually in 32 kHz sampling rate, despite the - // function name, and with a resampling factor of three becomes - // 96 kHz. - WebRtcSpl_Resample16khzTo48khz(tmp + i, samplesOut + i * 3, - (WebRtcSpl_State16khzTo48khz*) state3_, - tmp_mem); - } - outLen = outLen * 3; - free(tmp_mem); - free(tmp); - - return 0; - case kResamplerMode2To3: - if (maxLen < (lengthIn * 3 / 2)) - { - return -1; - } - // 2:6 - // We can only handle blocks of 160 samples - // Can be fixed, but I don't think it's needed - if ((lengthIn % 160) != 0) - { - return -1; - } - tmp = static_cast<int16_t*> (malloc(sizeof(int16_t) * lengthIn * 3)); - tmp_mem = (int32_t*)malloc(336 * sizeof(int32_t)); - for (size_t i = 0; i < lengthIn; i += 160) - { - WebRtcSpl_Resample16khzTo48khz(samplesIn + i, tmp + i * 3, - (WebRtcSpl_State16khzTo48khz *)state1_, - tmp_mem); - } - lengthIn = lengthIn * 3; - // 6:3 - WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut, (int32_t*)state2_); - outLen = lengthIn / 2; - free(tmp); - free(tmp_mem); - return 0; - case kResamplerMode2To11: - - // We can only handle blocks of 80 samples - // Can be fixed, but I don't think it's needed - if ((lengthIn % 80) != 0) - { - return -1; - } - if (maxLen < ((lengthIn * 11) / 2)) - { - return -1; - } - tmp = (int16_t*)malloc(sizeof(int16_t) * 2 * lengthIn); - // 1:2 - WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (int32_t*)state1_); - lengthIn *= 2; - - tmp_mem = (int32_t*)malloc(98 * sizeof(int32_t)); - - for (size_t i = 0; i < lengthIn; i += 80) - { - WebRtcSpl_Resample8khzTo22khz(tmp + i, samplesOut + (i * 11) / 4, - (WebRtcSpl_State8khzTo22khz *)state2_, - tmp_mem); - } - outLen = (lengthIn * 11) / 4; - free(tmp_mem); - free(tmp); - return 0; - case kResamplerMode4To11: - - // We can only handle blocks of 80 samples - // Can be fixed, but I don't think it's needed - if ((lengthIn % 80) != 0) - { - return -1; - } - if (maxLen < ((lengthIn * 11) / 4)) - { - return -1; - } - tmp_mem = (int32_t*)malloc(98 * sizeof(int32_t)); - - for (size_t i = 0; i < lengthIn; i += 80) - { - WebRtcSpl_Resample8khzTo22khz(samplesIn + i, samplesOut + (i * 11) / 4, - (WebRtcSpl_State8khzTo22khz *)state1_, - tmp_mem); - } - outLen = (lengthIn * 11) / 4; - free(tmp_mem); - return 0; - case kResamplerMode8To11: - // We can only handle blocks of 160 samples - // Can be fixed, but I don't think it's needed - if ((lengthIn % 160) != 0) - { - return -1; - } - if (maxLen < ((lengthIn * 11) / 8)) - { - return -1; - } - tmp_mem = (int32_t*)malloc(88 * sizeof(int32_t)); - - for (size_t i = 0; i < lengthIn; i += 160) - { - WebRtcSpl_Resample16khzTo22khz(samplesIn + i, samplesOut + (i * 11) / 8, - (WebRtcSpl_State16khzTo22khz *)state1_, - tmp_mem); - } - outLen = (lengthIn * 11) / 8; - free(tmp_mem); - return 0; - - case kResamplerMode11To16: - // We can only handle blocks of 110 samples - if ((lengthIn % 110) != 0) - { - return -1; - } - if (maxLen < ((lengthIn * 16) / 11)) - { - return -1; - } - - tmp_mem = (int32_t*)malloc(104 * sizeof(int32_t)); - tmp = (int16_t*)malloc((sizeof(int16_t) * lengthIn * 2)); - - WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (int32_t*)state1_); - - for (size_t i = 0; i < (lengthIn * 2); i += 220) - { - WebRtcSpl_Resample22khzTo16khz(tmp + i, samplesOut + (i / 220) * 160, - (WebRtcSpl_State22khzTo16khz *)state2_, - tmp_mem); - } - - outLen = (lengthIn * 16) / 11; - - free(tmp_mem); - free(tmp); - return 0; - - case kResamplerMode11To32: - - // We can only handle blocks of 110 samples - if ((lengthIn % 110) != 0) - { - return -1; - } - if (maxLen < ((lengthIn * 32) / 11)) - { - return -1; - } - - tmp_mem = (int32_t*)malloc(104 * sizeof(int32_t)); - tmp = (int16_t*)malloc((sizeof(int16_t) * lengthIn * 2)); - - // 11 -> 22 kHz in samplesOut - WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut, (int32_t*)state1_); - - // 22 -> 16 in tmp - for (size_t i = 0; i < (lengthIn * 2); i += 220) - { - WebRtcSpl_Resample22khzTo16khz(samplesOut + i, tmp + (i / 220) * 160, - (WebRtcSpl_State22khzTo16khz *)state2_, - tmp_mem); - } - - // 16 -> 32 in samplesOut - WebRtcSpl_UpsampleBy2(tmp, (lengthIn * 16) / 11, samplesOut, - (int32_t*)state3_); - - outLen = (lengthIn * 32) / 11; - - free(tmp_mem); - free(tmp); - return 0; - - case kResamplerMode2To1: - if (maxLen < (lengthIn / 2)) - { - return -1; - } - WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, samplesOut, (int32_t*)state1_); - outLen = lengthIn / 2; - return 0; - case kResamplerMode3To1: - // We can only handle blocks of 480 samples - // Can be fixed, but I don't think it's needed - if ((lengthIn % 480) != 0) - { - return -1; - } - if (maxLen < (lengthIn / 3)) - { - return -1; - } - tmp_mem = (int32_t*)malloc(496 * sizeof(int32_t)); - - for (size_t i = 0; i < lengthIn; i += 480) - { - WebRtcSpl_Resample48khzTo16khz(samplesIn + i, samplesOut + i / 3, - (WebRtcSpl_State48khzTo16khz *)state1_, - tmp_mem); - } - outLen = lengthIn / 3; - free(tmp_mem); - return 0; - case kResamplerMode4To1: - if (maxLen < (lengthIn / 4)) - { - return -1; - } - tmp = (int16_t*)malloc(sizeof(int16_t) * lengthIn / 2); - // 4:2 - WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, tmp, (int32_t*)state1_); - // 2:1 - WebRtcSpl_DownsampleBy2(tmp, lengthIn / 2, samplesOut, (int32_t*)state2_); - outLen = lengthIn / 4; - free(tmp); - return 0; - - case kResamplerMode6To1: - // We can only handle blocks of 480 samples - // Can be fixed, but I don't think it's needed - if ((lengthIn % 480) != 0) - { - return -1; - } - if (maxLen < (lengthIn / 6)) - { - return -1; - } - - tmp_mem = (int32_t*)malloc(496 * sizeof(int32_t)); - tmp = (int16_t*)malloc((sizeof(int16_t) * lengthIn) / 3); - - for (size_t i = 0; i < lengthIn; i += 480) - { - WebRtcSpl_Resample48khzTo16khz(samplesIn + i, tmp + i / 3, - (WebRtcSpl_State48khzTo16khz *)state1_, - tmp_mem); - } - outLen = lengthIn / 3; - free(tmp_mem); - WebRtcSpl_DownsampleBy2(tmp, outLen, samplesOut, (int32_t*)state2_); - free(tmp); - outLen = outLen / 2; - return 0; - case kResamplerMode12To1: - // We can only handle blocks of 480 samples - // Can be fixed, but I don't think it's needed - if ((lengthIn % 480) != 0) { - return -1; - } - if (maxLen < (lengthIn / 12)) { - return -1; - } - - tmp_mem = (int32_t*) malloc(496 * sizeof(int32_t)); - tmp = (int16_t*) malloc((sizeof(int16_t) * lengthIn) / 3); - tmp_2 = (int16_t*) malloc((sizeof(int16_t) * lengthIn) / 6); - // 12:4 - for (size_t i = 0; i < lengthIn; i += 480) { - // WebRtcSpl_Resample48khzTo16khz() takes a block of 480 samples - // as input and outputs a resampled block of 160 samples. The - // data is now actually in 96 kHz sampling rate, despite the - // function name, and with a resampling factor of 1/3 becomes - // 32 kHz. - WebRtcSpl_Resample48khzTo16khz(samplesIn + i, tmp + i / 3, - (WebRtcSpl_State48khzTo16khz*) state1_, - tmp_mem); - } - outLen = lengthIn / 3; - free(tmp_mem); - // 4:2 - WebRtcSpl_DownsampleBy2(tmp, outLen, tmp_2, (int32_t*) state2_); - outLen = outLen / 2; - free(tmp); - // 2:1 - WebRtcSpl_DownsampleBy2(tmp_2, outLen, samplesOut, - (int32_t*) state3_); - free(tmp_2); - outLen = outLen / 2; - return 0; - case kResamplerMode3To2: - if (maxLen < (lengthIn * 2 / 3)) - { - return -1; - } - // 3:6 - tmp = static_cast<int16_t*> (malloc(sizeof(int16_t) * lengthIn * 2)); - WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, (int32_t*)state1_); - lengthIn *= 2; - // 6:2 - // We can only handle blocks of 480 samples - // Can be fixed, but I don't think it's needed - if ((lengthIn % 480) != 0) - { - free(tmp); - return -1; - } - tmp_mem = (int32_t*)malloc(496 * sizeof(int32_t)); - for (size_t i = 0; i < lengthIn; i += 480) - { - WebRtcSpl_Resample48khzTo16khz(tmp + i, samplesOut + i / 3, - (WebRtcSpl_State48khzTo16khz *)state2_, - tmp_mem); - } - outLen = lengthIn / 3; - free(tmp); - free(tmp_mem); - return 0; - case kResamplerMode11To2: - // We can only handle blocks of 220 samples - // Can be fixed, but I don't think it's needed - if ((lengthIn % 220) != 0) - { - return -1; - } - if (maxLen < ((lengthIn * 2) / 11)) - { - return -1; - } - tmp_mem = (int32_t*)malloc(126 * sizeof(int32_t)); - tmp = (int16_t*)malloc((lengthIn * 4) / 11 * sizeof(int16_t)); - - for (size_t i = 0; i < lengthIn; i += 220) - { - WebRtcSpl_Resample22khzTo8khz(samplesIn + i, tmp + (i * 4) / 11, - (WebRtcSpl_State22khzTo8khz *)state1_, - tmp_mem); - } - lengthIn = (lengthIn * 4) / 11; - - WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut, - (int32_t*)state2_); - outLen = lengthIn / 2; - - free(tmp_mem); - free(tmp); - return 0; - case kResamplerMode11To4: - // We can only handle blocks of 220 samples - // Can be fixed, but I don't think it's needed - if ((lengthIn % 220) != 0) - { - return -1; - } - if (maxLen < ((lengthIn * 4) / 11)) - { - return -1; - } - tmp_mem = (int32_t*)malloc(126 * sizeof(int32_t)); - - for (size_t i = 0; i < lengthIn; i += 220) - { - WebRtcSpl_Resample22khzTo8khz(samplesIn + i, samplesOut + (i * 4) / 11, - (WebRtcSpl_State22khzTo8khz *)state1_, - tmp_mem); - } - outLen = (lengthIn * 4) / 11; - free(tmp_mem); - return 0; - case kResamplerMode11To8: - // We can only handle blocks of 160 samples - // Can be fixed, but I don't think it's needed - if ((lengthIn % 220) != 0) - { - return -1; - } - if (maxLen < ((lengthIn * 8) / 11)) - { - return -1; - } - tmp_mem = (int32_t*)malloc(104 * sizeof(int32_t)); - - for (size_t i = 0; i < lengthIn; i += 220) - { - WebRtcSpl_Resample22khzTo16khz(samplesIn + i, samplesOut + (i * 8) / 11, - (WebRtcSpl_State22khzTo16khz *)state1_, - tmp_mem); - } - outLen = (lengthIn * 8) / 11; - free(tmp_mem); - return 0; - break; + outLen = (lengthIn * 32) / 11; - } - return 0; + free(tmp_mem); + free(tmp); + return 0; + + case kResamplerMode2To1: + if (maxLen < (lengthIn / 2)) { + return -1; + } + WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, samplesOut, + static_cast<int32_t*>(state1_)); + outLen = lengthIn / 2; + return 0; + case kResamplerMode3To1: + // We can only handle blocks of 480 samples + // Can be fixed, but I don't think it's needed + if ((lengthIn % 480) != 0) { + return -1; + } + if (maxLen < (lengthIn / 3)) { + return -1; + } + tmp_mem = static_cast<int32_t*>(malloc(496 * sizeof(int32_t))); + + for (size_t i = 0; i < lengthIn; i += 480) { + WebRtcSpl_Resample48khzTo16khz( + samplesIn + i, samplesOut + i / 3, + static_cast<WebRtcSpl_State48khzTo16khz*>(state1_), tmp_mem); + } + outLen = lengthIn / 3; + free(tmp_mem); + return 0; + case kResamplerMode4To1: + if (maxLen < (lengthIn / 4)) { + return -1; + } + tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * lengthIn / 2)); + // 4:2 + WebRtcSpl_DownsampleBy2(samplesIn, lengthIn, tmp, + static_cast<int32_t*>(state1_)); + // 2:1 + WebRtcSpl_DownsampleBy2(tmp, lengthIn / 2, samplesOut, + static_cast<int32_t*>(state2_)); + outLen = lengthIn / 4; + free(tmp); + return 0; + + case kResamplerMode6To1: + // We can only handle blocks of 480 samples + // Can be fixed, but I don't think it's needed + if ((lengthIn % 480) != 0) { + return -1; + } + if (maxLen < (lengthIn / 6)) { + return -1; + } + + tmp_mem = static_cast<int32_t*>(malloc(496 * sizeof(int32_t))); + tmp = static_cast<int16_t*>(malloc((sizeof(int16_t) * lengthIn) / 3)); + + for (size_t i = 0; i < lengthIn; i += 480) { + WebRtcSpl_Resample48khzTo16khz( + samplesIn + i, tmp + i / 3, + static_cast<WebRtcSpl_State48khzTo16khz*>(state1_), tmp_mem); + } + outLen = lengthIn / 3; + free(tmp_mem); + WebRtcSpl_DownsampleBy2(tmp, outLen, samplesOut, + static_cast<int32_t*>(state2_)); + free(tmp); + outLen = outLen / 2; + return 0; + case kResamplerMode12To1: + // We can only handle blocks of 480 samples + // Can be fixed, but I don't think it's needed + if ((lengthIn % 480) != 0) { + return -1; + } + if (maxLen < (lengthIn / 12)) { + return -1; + } + + tmp_mem = static_cast<int32_t*>(malloc(496 * sizeof(int32_t))); + tmp = static_cast<int16_t*>(malloc((sizeof(int16_t) * lengthIn) / 3)); + tmp_2 = static_cast<int16_t*>(malloc((sizeof(int16_t) * lengthIn) / 6)); + // 12:4 + for (size_t i = 0; i < lengthIn; i += 480) { + // WebRtcSpl_Resample48khzTo16khz() takes a block of 480 samples + // as input and outputs a resampled block of 160 samples. The + // data is now actually in 96 kHz sampling rate, despite the + // function name, and with a resampling factor of 1/3 becomes + // 32 kHz. + WebRtcSpl_Resample48khzTo16khz( + samplesIn + i, tmp + i / 3, + static_cast<WebRtcSpl_State48khzTo16khz*>(state1_), tmp_mem); + } + outLen = lengthIn / 3; + free(tmp_mem); + // 4:2 + WebRtcSpl_DownsampleBy2(tmp, outLen, tmp_2, + static_cast<int32_t*>(state2_)); + outLen = outLen / 2; + free(tmp); + // 2:1 + WebRtcSpl_DownsampleBy2(tmp_2, outLen, samplesOut, + static_cast<int32_t*>(state3_)); + free(tmp_2); + outLen = outLen / 2; + return 0; + case kResamplerMode3To2: + if (maxLen < (lengthIn * 2 / 3)) { + return -1; + } + // 3:6 + tmp = static_cast<int16_t*>(malloc(sizeof(int16_t) * lengthIn * 2)); + WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, tmp, + static_cast<int32_t*>(state1_)); + lengthIn *= 2; + // 6:2 + // We can only handle blocks of 480 samples + // Can be fixed, but I don't think it's needed + if ((lengthIn % 480) != 0) { + free(tmp); + return -1; + } + tmp_mem = static_cast<int32_t*>(malloc(496 * sizeof(int32_t))); + for (size_t i = 0; i < lengthIn; i += 480) { + WebRtcSpl_Resample48khzTo16khz( + tmp + i, samplesOut + i / 3, + static_cast<WebRtcSpl_State48khzTo16khz*>(state2_), tmp_mem); + } + outLen = lengthIn / 3; + free(tmp); + free(tmp_mem); + return 0; + case kResamplerMode11To2: + // We can only handle blocks of 220 samples + // Can be fixed, but I don't think it's needed + if ((lengthIn % 220) != 0) { + return -1; + } + if (maxLen < ((lengthIn * 2) / 11)) { + return -1; + } + tmp_mem = static_cast<int32_t*>(malloc(126 * sizeof(int32_t))); + tmp = + static_cast<int16_t*>(malloc((lengthIn * 4) / 11 * sizeof(int16_t))); + + for (size_t i = 0; i < lengthIn; i += 220) { + WebRtcSpl_Resample22khzTo8khz( + samplesIn + i, tmp + (i * 4) / 11, + static_cast<WebRtcSpl_State22khzTo8khz*>(state1_), tmp_mem); + } + lengthIn = (lengthIn * 4) / 11; + + WebRtcSpl_DownsampleBy2(tmp, lengthIn, samplesOut, + static_cast<int32_t*>(state2_)); + outLen = lengthIn / 2; + + free(tmp_mem); + free(tmp); + return 0; + case kResamplerMode11To4: + // We can only handle blocks of 220 samples + // Can be fixed, but I don't think it's needed + if ((lengthIn % 220) != 0) { + return -1; + } + if (maxLen < ((lengthIn * 4) / 11)) { + return -1; + } + tmp_mem = static_cast<int32_t*>(malloc(126 * sizeof(int32_t))); + + for (size_t i = 0; i < lengthIn; i += 220) { + WebRtcSpl_Resample22khzTo8khz( + samplesIn + i, samplesOut + (i * 4) / 11, + static_cast<WebRtcSpl_State22khzTo8khz*>(state1_), tmp_mem); + } + outLen = (lengthIn * 4) / 11; + free(tmp_mem); + return 0; + case kResamplerMode11To8: + // We can only handle blocks of 160 samples + // Can be fixed, but I don't think it's needed + if ((lengthIn % 220) != 0) { + return -1; + } + if (maxLen < ((lengthIn * 8) / 11)) { + return -1; + } + tmp_mem = static_cast<int32_t*>(malloc(104 * sizeof(int32_t))); + + for (size_t i = 0; i < lengthIn; i += 220) { + WebRtcSpl_Resample22khzTo16khz( + samplesIn + i, samplesOut + (i * 8) / 11, + static_cast<WebRtcSpl_State22khzTo16khz*>(state1_), tmp_mem); + } + outLen = (lengthIn * 8) / 11; + free(tmp_mem); + return 0; + break; + } + return 0; } } // namespace webrtc |