mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 08:14:48 +02:00
Merge pull request #9273 from kencooke/audio-ambisonic-src2
Improved audio resampler
This commit is contained in:
commit
b56a15b60a
3 changed files with 3164 additions and 544 deletions
|
@ -99,18 +99,22 @@ static void cubicInterpolation(const float* input, float* output, int inputSize,
|
|||
}
|
||||
}
|
||||
|
||||
int AudioSRC::createRationalFilter(int upFactor, int downFactor, float gain) {
|
||||
int numTaps = PROTOTYPE_TAPS;
|
||||
int AudioSRC::createRationalFilter(int upFactor, int downFactor, float gain, Quality quality) {
|
||||
|
||||
int prototypeTaps = prototypeFilterTable[quality].taps;
|
||||
int prototypeCoefs = prototypeFilterTable[quality].coefs;
|
||||
const float* prototypeFilter = prototypeFilterTable[quality].filter;
|
||||
|
||||
int numTaps = prototypeTaps;
|
||||
int numPhases = upFactor;
|
||||
int numCoefs = numTaps * numPhases;
|
||||
int oldCoefs = numCoefs;
|
||||
int prototypeCoefs = PROTOTYPE_TAPS * PROTOTYPE_PHASES;
|
||||
|
||||
//
|
||||
// When downsampling, we can lower the filter cutoff by downFactor/upFactor using the
|
||||
// time-scaling property of the Fourier transform. The gain is adjusted accordingly.
|
||||
//
|
||||
if (downFactor > upFactor) {
|
||||
int oldCoefs = numCoefs;
|
||||
numCoefs = ((int64_t)oldCoefs * downFactor) / upFactor;
|
||||
numTaps = (numCoefs + upFactor - 1) / upFactor;
|
||||
gain *= (float)oldCoefs / numCoefs;
|
||||
|
@ -149,18 +153,22 @@ int AudioSRC::createRationalFilter(int upFactor, int downFactor, float gain) {
|
|||
return numTaps;
|
||||
}
|
||||
|
||||
int AudioSRC::createIrrationalFilter(int upFactor, int downFactor, float gain) {
|
||||
int numTaps = PROTOTYPE_TAPS;
|
||||
int AudioSRC::createIrrationalFilter(int upFactor, int downFactor, float gain, Quality quality) {
|
||||
|
||||
int prototypeTaps = prototypeFilterTable[quality].taps;
|
||||
int prototypeCoefs = prototypeFilterTable[quality].coefs;
|
||||
const float* prototypeFilter = prototypeFilterTable[quality].filter;
|
||||
|
||||
int numTaps = prototypeTaps;
|
||||
int numPhases = upFactor;
|
||||
int numCoefs = numTaps * numPhases;
|
||||
int oldCoefs = numCoefs;
|
||||
int prototypeCoefs = PROTOTYPE_TAPS * PROTOTYPE_PHASES;
|
||||
|
||||
//
|
||||
// When downsampling, we can lower the filter cutoff by downFactor/upFactor using the
|
||||
// time-scaling property of the Fourier transform. The gain is adjusted accordingly.
|
||||
//
|
||||
if (downFactor > upFactor) {
|
||||
int oldCoefs = numCoefs;
|
||||
numCoefs = ((int64_t)oldCoefs * downFactor) / upFactor;
|
||||
numTaps = (numCoefs + upFactor - 1) / upFactor;
|
||||
gain *= (float)oldCoefs / numCoefs;
|
||||
|
@ -1405,7 +1413,8 @@ int AudioSRC::render(float** inputs, float** outputs, int inputFrames) {
|
|||
return outputFrames;
|
||||
}
|
||||
|
||||
AudioSRC::AudioSRC(int inputSampleRate, int outputSampleRate, int numChannels) {
|
||||
AudioSRC::AudioSRC(int inputSampleRate, int outputSampleRate, int numChannels, Quality quality) {
|
||||
|
||||
assert(inputSampleRate > 0);
|
||||
assert(outputSampleRate > 0);
|
||||
assert(numChannels > 0);
|
||||
|
@ -1433,9 +1442,9 @@ AudioSRC::AudioSRC(int inputSampleRate, int outputSampleRate, int numChannels) {
|
|||
|
||||
// create the polyphase filter
|
||||
if (_step == 0) {
|
||||
_numTaps = createRationalFilter(_upFactor, _downFactor, 1.0f);
|
||||
_numTaps = createRationalFilter(_upFactor, _downFactor, 1.0f, quality);
|
||||
} else {
|
||||
_numTaps = createIrrationalFilter(_upFactor, _downFactor, 1.0f);
|
||||
_numTaps = createIrrationalFilter(_upFactor, _downFactor, 1.0f, quality);
|
||||
}
|
||||
|
||||
//printf("up=%d down=%.3f taps=%d\n", _upFactor, _downFactor + (LO32(_step)<<SRC_PHASEBITS) * Q32_TO_FLOAT, _numTaps);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
static const int SRC_MAX_CHANNELS = 4;
|
||||
|
||||
// polyphase filter
|
||||
static const int SRC_PHASEBITS = 8;
|
||||
static const int SRC_PHASEBITS = 9;
|
||||
static const int SRC_PHASES = (1 << SRC_PHASEBITS);
|
||||
static const int SRC_FRACBITS = 32 - SRC_PHASEBITS;
|
||||
static const uint32_t SRC_FRACMASK = (1 << SRC_FRACBITS) - 1;
|
||||
|
@ -31,7 +31,13 @@ static const int SRC_BLOCK = 256;
|
|||
class AudioSRC {
|
||||
|
||||
public:
|
||||
AudioSRC(int inputSampleRate, int outputSampleRate, int numChannels);
|
||||
enum Quality {
|
||||
LOW_QUALITY,
|
||||
MEDIUM_QUALITY,
|
||||
HIGH_QUALITY
|
||||
};
|
||||
|
||||
AudioSRC(int inputSampleRate, int outputSampleRate, int numChannels, Quality quality = MEDIUM_QUALITY);
|
||||
~AudioSRC();
|
||||
|
||||
// deinterleaved float input/output (native format)
|
||||
|
@ -70,8 +76,8 @@ private:
|
|||
int64_t _offset;
|
||||
int64_t _step;
|
||||
|
||||
int createRationalFilter(int upFactor, int downFactor, float gain);
|
||||
int createIrrationalFilter(int upFactor, int downFactor, float gain);
|
||||
int createRationalFilter(int upFactor, int downFactor, float gain, Quality quality);
|
||||
int createIrrationalFilter(int upFactor, int downFactor, float gain, Quality quality);
|
||||
|
||||
int multirateFilter1(const float* input0, float* output0, int inputFrames);
|
||||
int multirateFilter2(const float* input0, const float* input1, float* output0, float* output1, int inputFrames);
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue