From 694c76c886cf80566a03379192758274d0d3351a Mon Sep 17 00:00:00 2001 From: sinamas Date: Sun, 28 Apr 2013 15:17:48 +0200 Subject: [PATCH] common/chainresampler: hide more implementation --- common/resample/src/chainresampler.cpp | 70 ++++++++++--------- common/resample/src/chainresampler.h | 95 +++++++++----------------- common/resample/src/resamplerinfo.cpp | 17 ++--- 3 files changed, 78 insertions(+), 104 deletions(-) diff --git a/common/resample/src/chainresampler.cpp b/common/resample/src/chainresampler.cpp index eeac56ed..775f86bd 100644 --- a/common/resample/src/chainresampler.cpp +++ b/common/resample/src/chainresampler.cpp @@ -17,26 +17,36 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "chainresampler.h" -#include "defined_ptr.h" -#include +#include +#include -float ChainResampler::get2ChainMidRatio(float ratio, float finalRollOffLen, float midRollOffStartPlusEnd) { +static float get1ChainCost(float ratio, float finalRollOffLen) { + return ratio / finalRollOffLen; +} + +static float get2ChainMidRatio(float ratio, float finalRollOffLen, float midRollOffStartPlusEnd) { return 0.5f * ( std::sqrt(ratio * midRollOffStartPlusEnd * finalRollOffLen) + midRollOffStartPlusEnd); } -float ChainResampler::get2ChainCost(float ratio, float finalRollOffLen, float midRatio, - float midRollOffStartPlusEnd) +static float get2ChainCost(float ratio, float finalRollOffLen, float midRatio, + float midRollOffStartPlusEnd) { float midRollOffLen = midRatio * 2 - midRollOffStartPlusEnd; return midRatio * ratio / midRollOffLen + get1ChainCost(midRatio, finalRollOffLen); } -float ChainResampler::get3ChainRatio1(float ratio1, float const finalRollOffLen, float const ratio, - float const midRollOffStartPlusEnd) +static float get3ChainRatio2(float ratio1, + float finalRollOffLen, + float midRollOffStartPlusEnd) { + return get2ChainMidRatio(ratio1, finalRollOffLen, midRollOffStartPlusEnd); +} + +static float get3ChainRatio1(float ratio1, float const finalRollOffLen, float const ratio, + float const midRollOffStartPlusEnd) { - for (unsigned n = 8; n--;) { + for (int n = 8; n--;) { float ratio2 = get3ChainRatio2(ratio1, finalRollOffLen, midRollOffStartPlusEnd); ratio1 = ( std::sqrt(ratio * midRollOffStartPlusEnd * (2 - midRollOffStartPlusEnd / ratio2)) + midRollOffStartPlusEnd) * 0.5f; @@ -45,16 +55,20 @@ float ChainResampler::get3ChainRatio1(float ratio1, float const finalRollOffLen, return ratio1; } -float ChainResampler::get3ChainCost(float ratio, float finalRollOffLen, - float ratio1, float ratio2, float midRollOffStartPlusEnd) +static float get3ChainCost(float ratio, float finalRollOffLen, + float ratio1, float ratio2, float midRollOffStartPlusEnd) { float firstRollOffLen = ratio1 * 2 - midRollOffStartPlusEnd; return ratio1 * ratio / firstRollOffLen + get2ChainCost(ratio1, finalRollOffLen, ratio2, midRollOffStartPlusEnd); } -ChainResampler::ChainResampler() -: bigSinc_(0), buffer2_(0), periodSize_(0) +ChainResampler::ChainResampler(long inRate, long outRate, std::size_t periodSize) +: Resampler(inRate, outRate) +, bigSinc_(0) +, buffer2_(0) +, periodSize_(periodSize) +, maxOut_(0) { } @@ -121,26 +135,25 @@ void ChainResampler::downinitAddSincResamplers(double ratio, list_.push_back(bigSinc_); } -std::size_t ChainResampler::reallocateBuffer() { - std::size_t bufSz[2] = { 0, 0 }; - std::size_t inSz = periodSize_; +void ChainResampler::reallocateBuffer() { + std::size_t bufSize[2] = { 0, 0 }; + std::size_t inSize = periodSize_; int i = -1; for (List::iterator it = list_.begin(); it != list_.end(); ++it) { - inSz = (inSz * (*it)->mul() - 1) / (*it)->div() + 1; + inSize = (inSize * (*it)->mul() - 1) / (*it)->div() + 1; ++i; - if (inSz > bufSz[i & 1]) - bufSz[i & 1] = inSz; + if (inSize > bufSize[i & 1]) + bufSize[i & 1] = inSize; } - if (inSz >= bufSz[i & 1]) - bufSz[i & 1] = 0; + if (inSize >= bufSize[i & 1]) + bufSize[i & 1] = 0; - if (buffer_.size() < (bufSz[0] + bufSz[1]) * channels) - buffer_.reset((bufSz[0] + bufSz[1]) * channels); + if (buffer_.size() < (bufSize[0] + bufSize[1]) * channels) + buffer_.reset((bufSize[0] + bufSize[1]) * channels); - buffer2_ = bufSz[1] ? buffer_ + bufSz[0] * channels : 0; - - return (maxOut_ = inSz); + buffer2_ = bufSize[1] ? buffer_ + bufSize[0] * channels : 0; + maxOut_ = inSize; } void ChainResampler::adjustRate(long const inRate, long const outRate) { @@ -180,11 +193,6 @@ std::size_t ChainResampler::resample(short *const out, short const *const in, st return inlen; } -void ChainResampler::uninit() { - buffer2_ = 0; - buffer_.reset(); - periodSize_ = 0; - bigSinc_ = 0; +ChainResampler::~ChainResampler() { std::for_each(list_.begin(), list_.end(), defined_delete); - list_.clear(); } diff --git a/common/resample/src/chainresampler.h b/common/resample/src/chainresampler.h index 00f34a67..589da667 100644 --- a/common/resample/src/chainresampler.h +++ b/common/resample/src/chainresampler.h @@ -22,31 +22,28 @@ #include "../resampler.h" #include "../resamplerinfo.h" #include "array.h" -#include "subresampler.h" +#include "transfer_ptr.h" #include "upsampler.h" -#include -#include -#include -#include +#include #include +class SubResampler; + class ChainResampler : public Resampler { public: enum { channels = ResamplerInfo::channels }; - ChainResampler(); - virtual ~ChainResampler() { uninit(); } + template class Sinc> + static Resampler * create(long inRate, long outRate, std::size_t periodSize); + + virtual ~ChainResampler(); virtual void adjustRate(long inRate, long outRate); virtual void exactRatio(unsigned long &mul, unsigned long &div) const; virtual std::size_t maxOut(std::size_t /*inlen*/) const { return maxOut_; } virtual std::size_t resample(short *out, short const *in, std::size_t inlen); - template class Sinc> - std::size_t init(long inRate, long outRate, std::size_t periodSize); - void uninit(); - private: - typedef std::list List; + typedef std::list List; typedef SubResampler * (*CreateSinc)(unsigned div, float rollOffStart, float rollOffWidth, double gain); @@ -54,32 +51,14 @@ private: SubResampler *bigSinc_; Array buffer_; short *buffer2_; - std::size_t periodSize_; + std::size_t const periodSize_; std::size_t maxOut_; - static float get1ChainCost(float ratio, float finalRollOffLen) { - return ratio / finalRollOffLen; - } - - static float get2ChainMidRatio(float ratio, float finalRollOffLen, - float midRollOffStartPlusEnd); - static float get2ChainCost(float ratio, float finalRollOffLen, float midRatio, - float midRollOffStartPlusEnd); - - static float get3ChainRatio2(float ratio1, - float finalRollOffLen, - float midRollOffStartPlusEnd) { - return get2ChainMidRatio(ratio1, finalRollOffLen, midRollOffStartPlusEnd); - } - - static float get3ChainRatio1(float ratio1, float finalRollOffLen, float ratio, - float midRollOffStartPlusEnd); - static float get3ChainCost(float ratio, float finalRollOffLen, float ratio1, float ratio2, - float midRollOffStartPlusEnd); - + 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); + void reallocateBuffer(); template static SubResampler * createSinc(unsigned div, @@ -87,33 +66,29 @@ private: return new Sinc(div, typename Sinc::RollOff(rollOffStart, rollOffWidth), gain); } - template class Sinc> - std::size_t downinit(long inRate, long outRate, std::size_t periodSize); + template class Sinc> + void downinit(long inRate, long outRate); - template class Sinc> - std::size_t upinit(long inRate, long outRate, std::size_t periodSize); - - std::size_t reallocateBuffer(); + template class Sinc> + void upinit(long inRate, long outRate); }; -template class Sinc> -std::size_t ChainResampler::init(long inRate, long outRate, std::size_t periodSize) { - setRate(inRate, outRate); - +template class Sinc> +Resampler * ChainResampler::create(long inRate, long outRate, std::size_t periodSize) { + transfer_ptr r(new ChainResampler(inRate, outRate, periodSize)); if (outRate > inRate) - return upinit(inRate, outRate, periodSize); + r->upinit(inRate, outRate); else - return downinit(inRate, outRate, periodSize); + r->downinit(inRate, outRate); + + return r.release(); } -template class Sinc> -std::size_t ChainResampler::downinit(long const inRate, - long const outRate, - std::size_t const periodSize) { +template class Sinc> +void ChainResampler::downinit(long const inRate, + long const outRate) { typedef Sinc BigSinc; typedef Sinc SmallSinc; - uninit(); - periodSize_ = periodSize; double ratio = static_cast(inRate) / outRate; double gain = 1.0; @@ -125,19 +100,17 @@ std::size_t ChainResampler::downinit(long const inRate, gain *= 1.0 / BigSinc::Cic::gain(div); } - downinitAddSincResamplers(ratio, outRate, createSinc, - createSinc, BigSinc::MUL, SmallSinc::MUL, gain); - return reallocateBuffer(); + downinitAddSincResamplers(ratio, outRate, + createSinc, createSinc, + BigSinc::MUL, SmallSinc::MUL, gain); + reallocateBuffer(); } -template class Sinc> -std::size_t ChainResampler::upinit(long const inRate, - long const outRate, - std::size_t const periodSize) { +template class Sinc> +void ChainResampler::upinit(long const inRate, + long const outRate) { typedef Sinc BigSinc; typedef Sinc SmallSinc; - uninit(); - periodSize_ = periodSize; double ratio = static_cast(outRate) / inRate; // Spectral images above 20 kHz assumed inaudible @@ -155,7 +128,7 @@ std::size_t ChainResampler::upinit(long const inRate, typename BigSinc::RollOff(0.5f * (1 - rollOff), 0.5f * rollOff), 1.0); list_.push_front(bigSinc_); // note: inserted at the front - return reallocateBuffer(); + reallocateBuffer(); } #endif diff --git a/common/resample/src/resamplerinfo.cpp b/common/resample/src/resamplerinfo.cpp index 2f333703..363fd443 100644 --- a/common/resample/src/resamplerinfo.cpp +++ b/common/resample/src/resamplerinfo.cpp @@ -29,20 +29,13 @@ static Resampler * createLinint(long inRate, long outRate, std::size_t ) { return new Linint(inRate, outRate); } -template class T> -static Resampler * createChainResampler(long inRate, long outRate, std::size_t periodSize) { - ChainResampler *r = new ChainResampler; - r->init(inRate, outRate, periodSize); - return r; -} - ResamplerInfo const ResamplerInfo::resamplers_[] = { { "Fast", createLinint }, - { "High quality (polyphase FIR)", createChainResampler }, -// { "Hamming windowed sinc (~50 dB SNR)", createChainResampler }, -// { "Blackman windowed sinc (~70 dB SNR)", createChainResampler }, - { "Very high quality (polyphase FIR)", createChainResampler }, - { "Highest quality (polyphase FIR)", createChainResampler }, + { "High quality (polyphase FIR)", ChainResampler::create }, +// { "Hamming windowed sinc (~50 dB SNR)", ChainResampler::create }, +// { "Blackman windowed sinc (~70 dB SNR)", ChainResampler::create }, + { "Very high quality (polyphase FIR)", ChainResampler::create }, + { "Highest quality (polyphase FIR)", ChainResampler::create }, }; std::size_t const ResamplerInfo::num_ =