101 lines
3.6 KiB
C++
101 lines
3.6 KiB
C++
/* Copyright (C) 2015-2022 Sergey V. Mikayev
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 2.1 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef SRCTOOLS_IIR_2X_RESAMPLER_H
|
|
#define SRCTOOLS_IIR_2X_RESAMPLER_H
|
|
|
|
#include "ResamplerStage.h"
|
|
|
|
namespace SRCTools {
|
|
|
|
static const unsigned int IIR_RESAMPER_CHANNEL_COUNT = 2;
|
|
static const unsigned int IIR_SECTION_ORDER = 2;
|
|
|
|
typedef FloatSample IIRCoefficient;
|
|
typedef FloatSample BufferedSample;
|
|
|
|
typedef BufferedSample SectionBuffer[IIR_SECTION_ORDER];
|
|
|
|
// Non-trivial coefficients of a 2nd-order section of a parallel bank
|
|
// (zero-order numerator coefficient is always zero, zero-order denominator coefficient is always unity)
|
|
struct IIRSection {
|
|
IIRCoefficient num1;
|
|
IIRCoefficient num2;
|
|
IIRCoefficient den1;
|
|
IIRCoefficient den2;
|
|
};
|
|
|
|
class IIRResampler : public ResamplerStage {
|
|
public:
|
|
enum Quality {
|
|
// Used when providing custom IIR filter coefficients.
|
|
CUSTOM,
|
|
// Use fast elliptic filter with symmetric ripple: N=8, Ap=As=-99 dB, fp=0.125, fs = 0.25 (in terms of sample rate)
|
|
FAST,
|
|
// Use average elliptic filter with symmetric ripple: N=12, Ap=As=-106 dB, fp=0.193, fs = 0.25 (in terms of sample rate)
|
|
GOOD,
|
|
// Use sharp elliptic filter with symmetric ripple: N=18, Ap=As=-106 dB, fp=0.238, fs = 0.25 (in terms of sample rate)
|
|
BEST
|
|
};
|
|
|
|
// Returns the retained fraction of the passband for the given standard quality value
|
|
static double getPassbandFractionForQuality(Quality quality);
|
|
|
|
protected:
|
|
explicit IIRResampler(const Quality quality);
|
|
explicit IIRResampler(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[]);
|
|
~IIRResampler();
|
|
|
|
const struct Constants {
|
|
// Coefficient of the 0-order FIR part
|
|
IIRCoefficient fir;
|
|
// 2nd-order sections that comprise a parallel bank
|
|
const IIRSection *sections;
|
|
// Number of 2nd-order sections
|
|
unsigned int sectionsCount;
|
|
// Delay line per channel per section
|
|
SectionBuffer *buffer;
|
|
|
|
Constants(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[], const Quality quality);
|
|
} constants;
|
|
}; // class IIRResampler
|
|
|
|
class IIR2xInterpolator : public IIRResampler {
|
|
public:
|
|
explicit IIR2xInterpolator(const Quality quality);
|
|
explicit IIR2xInterpolator(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[]);
|
|
|
|
void process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength);
|
|
unsigned int estimateInLength(const unsigned int outLength) const;
|
|
|
|
private:
|
|
FloatSample lastInputSamples[IIR_RESAMPER_CHANNEL_COUNT];
|
|
unsigned int phase;
|
|
};
|
|
|
|
class IIR2xDecimator : public IIRResampler {
|
|
public:
|
|
explicit IIR2xDecimator(const Quality quality);
|
|
explicit IIR2xDecimator(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[]);
|
|
|
|
void process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength);
|
|
unsigned int estimateInLength(const unsigned int outLength) const;
|
|
};
|
|
|
|
} // namespace SRCTools
|
|
|
|
#endif // SRCTOOLS_IIR_2X_RESAMPLER_H
|