aboutsummaryrefslogtreecommitdiff
path: root/externals/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'externals/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp')
-rw-r--r--externals/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp171
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;
- }
- }
-}