common/chainresampler: less template bloat
This commit is contained in:
parent
5558b1e461
commit
0f063671be
@ -76,8 +76,6 @@ void ChainResampler::downinitAddSincResamplers(double ratio,
|
||||
float const outRate,
|
||||
CreateSinc const createBigSinc,
|
||||
CreateSinc const createSmallSinc,
|
||||
unsigned const bigSincMul,
|
||||
unsigned const smallSincMul,
|
||||
double gain)
|
||||
{
|
||||
// For high outRate: Start roll-off at 36 kHz continue until outRate Hz,
|
||||
@ -92,18 +90,18 @@ void ChainResampler::downinitAddSincResamplers(double ratio,
|
||||
float const midRollOffStartPlusEnd = midRollOffStart + midRollOffEnd;
|
||||
float const ideal2ChainMidRatio = get2ChainMidRatio(ratio, finalRollOffLen,
|
||||
midRollOffStartPlusEnd);
|
||||
int div_2c = int(ratio * smallSincMul / ideal2ChainMidRatio + 0.5f);
|
||||
double ratio_2c = ratio * smallSincMul / div_2c;
|
||||
int div_2c = int(ratio * small_sinc_mul / ideal2ChainMidRatio + 0.5f);
|
||||
double ratio_2c = ratio * small_sinc_mul / div_2c;
|
||||
float cost_2c = get2ChainCost(ratio, finalRollOffLen, ratio_2c, midRollOffStartPlusEnd);
|
||||
if (cost_2c < get1ChainCost(ratio, finalRollOffLen)) {
|
||||
float const ideal3ChainRatio1 = get3ChainRatio1(ratio_2c, finalRollOffLen,
|
||||
ratio, midRollOffStartPlusEnd);
|
||||
int const div1_3c = int(ratio * smallSincMul / ideal3ChainRatio1 + 0.5f);
|
||||
double const ratio1_3c = ratio * smallSincMul / div1_3c;
|
||||
int const div1_3c = int(ratio * small_sinc_mul / ideal3ChainRatio1 + 0.5f);
|
||||
double const ratio1_3c = ratio * small_sinc_mul / div1_3c;
|
||||
float const ideal3ChainRatio2 = get3ChainRatio2(ratio1_3c, finalRollOffLen,
|
||||
midRollOffStartPlusEnd);
|
||||
int const div2_3c = int(ratio1_3c * smallSincMul / ideal3ChainRatio2 + 0.5f);
|
||||
double const ratio2_3c = ratio1_3c * smallSincMul / div2_3c;
|
||||
int const div2_3c = int(ratio1_3c * small_sinc_mul / ideal3ChainRatio2 + 0.5f);
|
||||
double const ratio2_3c = ratio1_3c * small_sinc_mul / div2_3c;
|
||||
if (get3ChainCost(ratio, finalRollOffLen, ratio1_3c,
|
||||
ratio2_3c, midRollOffStartPlusEnd) < cost_2c) {
|
||||
list_.push_back(createSmallSinc(div1_3c,
|
||||
@ -128,13 +126,36 @@ void ChainResampler::downinitAddSincResamplers(double ratio,
|
||||
float rollOffStart = 0.5f * (1.0f
|
||||
+ std::max((outRate - 40000.0f) * outPeriod, 0.0f)
|
||||
- finalRollOffLen) / ratio;
|
||||
bigSinc_ = createBigSinc(static_cast<int>(bigSincMul * ratio + 0.5),
|
||||
bigSinc_ = createBigSinc(static_cast<int>(big_sinc_mul * ratio + 0.5),
|
||||
rollOffStart,
|
||||
0.5f * finalRollOffLen / ratio,
|
||||
gain);
|
||||
list_.push_back(bigSinc_);
|
||||
}
|
||||
|
||||
void ChainResampler::upinit(long const inRate,
|
||||
long const outRate,
|
||||
CreateSinc const createSinc) {
|
||||
double ratio = static_cast<double>(outRate) / inRate;
|
||||
// Spectral images above 20 kHz assumed inaudible
|
||||
// this post-polyphase zero stuffing causes some power loss though.
|
||||
{
|
||||
int const div = outRate / std::max(inRate, 40000l);
|
||||
if (div >= 2) {
|
||||
list_.push_front(new Upsampler<channels>(div));
|
||||
ratio /= div;
|
||||
}
|
||||
}
|
||||
|
||||
float const rollOffLen = std::max((inRate - 36000.0f) / inRate, 0.2f);
|
||||
bigSinc_ = createSinc(static_cast<int>(big_sinc_mul / ratio + 0.5),
|
||||
0.5f * (1 - rollOffLen),
|
||||
0.5f * rollOffLen,
|
||||
1.0);
|
||||
list_.push_front(bigSinc_); // note: inserted at the front
|
||||
reallocateBuffer();
|
||||
}
|
||||
|
||||
void ChainResampler::reallocateBuffer() {
|
||||
std::size_t bufSize[2] = { 0, 0 };
|
||||
std::size_t inSize = periodSize_;
|
||||
|
@ -46,6 +46,8 @@ private:
|
||||
typedef std::list<SubResampler *> List;
|
||||
typedef SubResampler * (*CreateSinc)(unsigned div, float rollOffStart,
|
||||
float rollOffWidth, double gain);
|
||||
enum { big_sinc_mul = 2048 };
|
||||
enum { small_sinc_mul = 32 };
|
||||
|
||||
List list_;
|
||||
SubResampler *bigSinc_;
|
||||
@ -56,8 +58,10 @@ private:
|
||||
|
||||
ChainResampler(long inRate, long outRate, std::size_t periodSize);
|
||||
void downinitAddSincResamplers(double ratio, float outRate,
|
||||
CreateSinc createBigSinc, CreateSinc createSmallSinc,
|
||||
unsigned bigSincMul, unsigned smallSincMul, double gain);
|
||||
CreateSinc createBigSinc,
|
||||
CreateSinc createSmallSinc,
|
||||
double gain);
|
||||
void upinit(long inRate, long outRate, CreateSinc);
|
||||
void reallocateBuffer();
|
||||
|
||||
template<class Sinc>
|
||||
@ -68,17 +72,15 @@ private:
|
||||
|
||||
template<template<unsigned, unsigned> class Sinc>
|
||||
void downinit(long inRate, long outRate);
|
||||
|
||||
template<template<unsigned, unsigned> class Sinc>
|
||||
void upinit(long inRate, long outRate);
|
||||
};
|
||||
|
||||
template<template<unsigned, unsigned> class Sinc>
|
||||
Resampler * ChainResampler::create(long inRate, long outRate, std::size_t periodSize) {
|
||||
transfer_ptr<ChainResampler> r(new ChainResampler(inRate, outRate, periodSize));
|
||||
if (outRate > inRate)
|
||||
r->upinit<Sinc>(inRate, outRate);
|
||||
else
|
||||
if (outRate > inRate) {
|
||||
r->upinit(inRate, outRate,
|
||||
createSinc< Sinc<channels, big_sinc_mul> >);
|
||||
} else
|
||||
r->downinit<Sinc>(inRate, outRate);
|
||||
|
||||
return r.release();
|
||||
@ -87,8 +89,8 @@ Resampler * ChainResampler::create(long inRate, long outRate, std::size_t period
|
||||
template<template<unsigned, unsigned> class Sinc>
|
||||
void ChainResampler::downinit(long const inRate,
|
||||
long const outRate) {
|
||||
typedef Sinc<channels, 2048> BigSinc;
|
||||
typedef Sinc<channels, 32> SmallSinc;
|
||||
typedef Sinc<channels, big_sinc_mul> BigSinc;
|
||||
typedef Sinc<channels, small_sinc_mul> SmallSinc;
|
||||
|
||||
double ratio = static_cast<double>(inRate) / outRate;
|
||||
double gain = 1.0;
|
||||
@ -102,32 +104,7 @@ void ChainResampler::downinit(long const inRate,
|
||||
|
||||
downinitAddSincResamplers(ratio, outRate,
|
||||
createSinc<BigSinc>, createSinc<SmallSinc>,
|
||||
BigSinc::MUL, SmallSinc::MUL, gain);
|
||||
reallocateBuffer();
|
||||
}
|
||||
|
||||
template<template<unsigned, unsigned> class Sinc>
|
||||
void ChainResampler::upinit(long const inRate,
|
||||
long const outRate) {
|
||||
typedef Sinc<channels, 2048> BigSinc;
|
||||
typedef Sinc<channels, 32> SmallSinc;
|
||||
|
||||
double ratio = static_cast<double>(outRate) / inRate;
|
||||
// Spectral images above 20 kHz assumed inaudible
|
||||
// this post-polyphase zero stuffing causes some power loss though.
|
||||
{
|
||||
int const div = outRate / std::max(inRate, 40000l);
|
||||
if (div >= 2) {
|
||||
list_.push_front(new Upsampler<channels>(div));
|
||||
ratio /= div;
|
||||
}
|
||||
}
|
||||
|
||||
float const rollOff = std::max((inRate - 36000.0f) / inRate, 0.2f);
|
||||
bigSinc_ = new BigSinc(static_cast<int>(BigSinc::MUL / ratio + 0.5),
|
||||
typename BigSinc::RollOff(0.5f * (1 - rollOff), 0.5f * rollOff),
|
||||
1.0);
|
||||
list_.push_front(bigSinc_); // note: inserted at the front
|
||||
gain);
|
||||
reallocateBuffer();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user