diff options
Diffstat (limited to 'externals/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp')
| -rw-r--r-- | externals/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp | 171 |
1 files changed, 0 insertions, 171 deletions
diff --git a/externals/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp b/externals/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp deleted file mode 100644 index 245b669db4..0000000000 --- a/externals/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <math.h> - -#include "IntegerRatio.h" -#include "LinearResampler.h" -#include "MultiChannelResampler.h" -#include "PolyphaseResampler.h" -#include "PolyphaseResamplerMono.h" -#include "PolyphaseResamplerStereo.h" -#include "SincResampler.h" -#include "SincResamplerStereo.h" - -using namespace RESAMPLER_OUTER_NAMESPACE::resampler; - -MultiChannelResampler::MultiChannelResampler(const MultiChannelResampler::Builder &builder) - : mNumTaps(builder.getNumTaps()) - , mX(static_cast<size_t>(builder.getChannelCount()) - * static_cast<size_t>(builder.getNumTaps()) * 2) - , mSingleFrame(builder.getChannelCount()) - , mChannelCount(builder.getChannelCount()) - { - // Reduce sample rates to the smallest ratio. - // For example 44100/48000 would become 147/160. - IntegerRatio ratio(builder.getInputRate(), builder.getOutputRate()); - ratio.reduce(); - mNumerator = ratio.getNumerator(); - mDenominator = ratio.getDenominator(); - mIntegerPhase = mDenominator; // so we start with a write needed -} - -// static factory method -MultiChannelResampler *MultiChannelResampler::make(int32_t channelCount, - int32_t inputRate, - int32_t outputRate, - Quality quality) { - Builder builder; - builder.setInputRate(inputRate); - builder.setOutputRate(outputRate); - builder.setChannelCount(channelCount); - - switch (quality) { - case Quality::Fastest: - builder.setNumTaps(2); - break; - case Quality::Low: - builder.setNumTaps(4); - break; - case Quality::Medium: - default: - builder.setNumTaps(8); - break; - case Quality::High: - builder.setNumTaps(16); - break; - case Quality::Best: - builder.setNumTaps(32); - break; - } - - // Set the cutoff frequency so that we do not get aliasing when down-sampling. - if (inputRate > outputRate) { - builder.setNormalizedCutoff(kDefaultNormalizedCutoff); - } - return builder.build(); -} - -MultiChannelResampler *MultiChannelResampler::Builder::build() { - if (getNumTaps() == 2) { - // Note that this does not do low pass filteringh. - return new LinearResampler(*this); - } - IntegerRatio ratio(getInputRate(), getOutputRate()); - ratio.reduce(); - bool usePolyphase = (getNumTaps() * ratio.getDenominator()) <= kMaxCoefficients; - if (usePolyphase) { - if (getChannelCount() == 1) { - return new PolyphaseResamplerMono(*this); - } else if (getChannelCount() == 2) { - return new PolyphaseResamplerStereo(*this); - } else { - return new PolyphaseResampler(*this); - } - } else { - // Use less optimized resampler that uses a float phaseIncrement. - // TODO mono resampler - if (getChannelCount() == 2) { - return new SincResamplerStereo(*this); - } else { - return new SincResampler(*this); - } - } -} - -void MultiChannelResampler::writeFrame(const float *frame) { - // Move cursor before write so that cursor points to last written frame in read. - if (--mCursor < 0) { - mCursor = getNumTaps() - 1; - } - float *dest = &mX[static_cast<size_t>(mCursor) * static_cast<size_t>(getChannelCount())]; - int offset = getNumTaps() * getChannelCount(); - for (int channel = 0; channel < getChannelCount(); channel++) { - // Write twice so we avoid having to wrap when reading. - dest[channel] = dest[channel + offset] = frame[channel]; - } -} - -float MultiChannelResampler::sinc(float radians) { - if (fabsf(radians) < 1.0e-9f) return 1.0f; // avoid divide by zero - return sinf(radians) / radians; // Sinc function -} - -// Generate coefficients in the order they will be used by readFrame(). -// This is more complicated but readFrame() is called repeatedly and should be optimized. -void MultiChannelResampler::generateCoefficients(int32_t inputRate, - int32_t outputRate, - int32_t numRows, - double phaseIncrement, - float normalizedCutoff) { - mCoefficients.resize(static_cast<size_t>(getNumTaps()) * static_cast<size_t>(numRows)); - int coefficientIndex = 0; - double phase = 0.0; // ranges from 0.0 to 1.0, fraction between samples - // Stretch the sinc function for low pass filtering. - const float cutoffScaler = (outputRate < inputRate) - ? (normalizedCutoff * (float)outputRate / inputRate) - : 1.0f; // Do not filter when upsampling. - const int numTapsHalf = getNumTaps() / 2; // numTaps must be even. - const float numTapsHalfInverse = 1.0f / numTapsHalf; - for (int i = 0; i < numRows; i++) { - float tapPhase = phase - numTapsHalf; - float gain = 0.0; // sum of raw coefficients - int gainCursor = coefficientIndex; - for (int tap = 0; tap < getNumTaps(); tap++) { - float radians = tapPhase * M_PI; - -#if MCR_USE_KAISER - float window = mKaiserWindow(tapPhase * numTapsHalfInverse); -#else - float window = mCoshWindow(static_cast<double>(tapPhase) * numTapsHalfInverse); -#endif - float coefficient = sinc(radians * cutoffScaler) * window; - mCoefficients.at(coefficientIndex++) = coefficient; - gain += coefficient; - tapPhase += 1.0; - } - phase += phaseIncrement; - while (phase >= 1.0) { - phase -= 1.0; - } - - // Correct for gain variations. - float gainCorrection = 1.0 / gain; // normalize the gain - for (int tap = 0; tap < getNumTaps(); tap++) { - mCoefficients.at(gainCursor + tap) *= gainCorrection; - } - } -} |
