Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
/* 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_FIR_RESAMPLER_H
#define SRCTOOLS_FIR_RESAMPLER_H
#include "ResamplerStage.h"
namespace SRCTools {
typedef FloatSample FIRCoefficient;
static const unsigned int FIR_INTERPOLATOR_CHANNEL_COUNT = 2;
class FIRResampler : public ResamplerStage {
public:
FIRResampler(const unsigned int upsampleFactor, const double downsampleFactor, const FIRCoefficient kernel[], const unsigned int kernelLength);
~FIRResampler();
void process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength);
unsigned int estimateInLength(const unsigned int outLength) const;
private:
const struct Constants {
// Filter coefficients
const FIRCoefficient *taps;
// Indicates whether to interpolate filter taps
bool usePhaseInterpolation;
// Size of array of filter coefficients
unsigned int numberOfTaps;
// Upsampling factor
unsigned int numberOfPhases;
// Downsampling factor
double phaseIncrement;
// Index of last delay line element, generally greater than numberOfTaps to form a proper binary mask
unsigned int delayLineMask;
// Delay line
FloatSample(*ringBuffer)[FIR_INTERPOLATOR_CHANNEL_COUNT];
Constants(const unsigned int upsampleFactor, const double downsampleFactor, const FIRCoefficient kernel[], const unsigned int kernelLength);
} constants;
// Index of current sample in delay line
unsigned int ringBufferPosition;
// Current phase
double phase;
bool needNextInSample() const;
void addInSamples(const FloatSample *&inSamples);
void getOutSamplesStereo(FloatSample *&outSamples);
}; // class FIRResampler
} // namespace SRCTools
#endif // SRCTOOLS_FIR_RESAMPLER_H

View File

@@ -0,0 +1,34 @@
/* 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_FLOAT_SAMPLE_PROVIDER_H
#define SRCTOOLS_FLOAT_SAMPLE_PROVIDER_H
namespace SRCTools {
typedef float FloatSample;
/** Interface defines an abstract source of samples. It can either define a single channel stream or a stream with interleaved channels. */
class FloatSampleProvider {
public:
virtual ~FloatSampleProvider() {}
virtual void getOutputSamples(FloatSample *outBuffer, unsigned int size) = 0;
};
} // namespace SRCTools
#endif // SRCTOOLS_FLOAT_SAMPLE_PROVIDER_H

View File

@@ -0,0 +1,100 @@
/* 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

View File

@@ -0,0 +1,42 @@
/* 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_LINEAR_RESAMPLER_H
#define SRCTOOLS_LINEAR_RESAMPLER_H
#include "ResamplerStage.h"
namespace SRCTools {
static const unsigned int LINEAR_RESAMPER_CHANNEL_COUNT = 2;
class LinearResampler : public ResamplerStage {
public:
LinearResampler(double sourceSampleRate, double targetSampleRate);
~LinearResampler() {}
unsigned int estimateInLength(const unsigned int outLength) const;
void process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength);
private:
const double inputToOutputRatio;
double position;
FloatSample lastInputSamples[LINEAR_RESAMPER_CHANNEL_COUNT];
};
} // namespace SRCTools
#endif // SRCTOOLS_LINEAR_RESAMPLER_H

View File

@@ -0,0 +1,63 @@
/* 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_RESAMPLER_MODEL_H
#define SRCTOOLS_RESAMPLER_MODEL_H
#include "FloatSampleProvider.h"
namespace SRCTools {
class ResamplerStage;
/** Model consists of one or more ResampleStage instances connected in a cascade. */
namespace ResamplerModel {
// Seems to be a good choice for 16-bit integer samples.
static const double DEFAULT_DB_SNR = 106;
// When using linear interpolation, oversampling factor necessary to achieve the DEFAULT_DB_SNR is about 256.
// This figure is the upper estimation, and it can be found by analysing the frequency response of the linear interpolator.
// When less SNR is desired, this value should also decrease in accordance.
static const unsigned int DEFAULT_WINDOWED_SINC_MAX_DOWNSAMPLE_FACTOR = 256;
// In the default resampler model, the input to the windowed sinc filter is always at least 2x oversampled during upsampling,
// so oversampling factor of 128 should be sufficient to achieve the DEFAULT_DB_SNR with linear interpolation.
static const unsigned int DEFAULT_WINDOWED_SINC_MAX_UPSAMPLE_FACTOR = DEFAULT_WINDOWED_SINC_MAX_DOWNSAMPLE_FACTOR / 2;
enum Quality {
// Use when the speed is more important than the audio quality.
FASTEST,
// Use FAST quality setting of the IIR stage (50% of passband retained).
FAST,
// Use GOOD quality setting of the IIR stage (77% of passband retained).
GOOD,
// Use BEST quality setting of the IIR stage (95% of passband retained).
BEST
};
FloatSampleProvider &createResamplerModel(FloatSampleProvider &source, double sourceSampleRate, double targetSampleRate, Quality quality);
FloatSampleProvider &createResamplerModel(FloatSampleProvider &source, ResamplerStage **stages, unsigned int stageCount);
FloatSampleProvider &createResamplerModel(FloatSampleProvider &source, ResamplerStage &stage);
void freeResamplerModel(FloatSampleProvider &model, FloatSampleProvider &source);
} // namespace ResamplerModel
} // namespace SRCTools
#endif // SRCTOOLS_RESAMPLER_MODEL_H

View File

@@ -0,0 +1,38 @@
/* 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_RESAMPLER_STAGE_H
#define SRCTOOLS_RESAMPLER_STAGE_H
#include "FloatSampleProvider.h"
namespace SRCTools {
/** Interface defines an abstract source of samples. It can either define a single channel stream or a stream with interleaved channels. */
class ResamplerStage {
public:
virtual ~ResamplerStage() {}
/** Returns a lower estimation of required number of input samples to produce the specified number of output samples. */
virtual unsigned int estimateInLength(const unsigned int outLength) const = 0;
/** Generates output samples. The arguments are adjusted in accordance with the number of samples processed. */
virtual void process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength) = 0;
};
} // namespace SRCTools
#endif // SRCTOOLS_RESAMPLER_STAGE_H

View File

@@ -0,0 +1,46 @@
/* 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_SINC_RESAMPLER_H
#define SRCTOOLS_SINC_RESAMPLER_H
#include "FIRResampler.h"
namespace SRCTools {
class ResamplerStage;
namespace SincResampler {
ResamplerStage *createSincResampler(const double inputFrequency, const double outputFrequency, const double passbandFrequency, const double stopbandFrequency, const double dbSNR, const unsigned int maxUpsampleFactor);
namespace Utils {
void computeResampleFactors(unsigned int &upsampleFactor, double &downsampleFactor, const double inputFrequency, const double outputFrequency, const unsigned int maxUpsampleFactor);
unsigned int greatestCommonDivisor(unsigned int a, unsigned int b);
}
namespace KaizerWindow {
double estimateBeta(double dbRipple);
unsigned int estimateOrder(double dbRipple, double fp, double fs);
double bessel(const double x);
void windowedSinc(FIRCoefficient kernel[], const unsigned int order, const double fc, const double beta, const double amp);
}
} // namespace SincResampler
} // namespace SRCTools
#endif // SRCTOOLS_SINC_RESAMPLER_H