#include #include "AudioMath.h" #include "ButterworthFilterDesigner.h" #include "LookupTableFactory.h" #include "ObjectCache.h" template std::shared_ptr> ObjectCache::getBipolarAudioTaper() { std::shared_ptr< LookupTableParams> ret = bipolarAudioTaper.lock(); if (!ret) { ret = std::make_shared>(); LookupTableFactory::makeBipolarAudioTaper(*ret); bipolarAudioTaper = ret; } return ret; } template std::shared_ptr> ObjectCache::getAudioTaper() { std::shared_ptr< LookupTableParams> ret = audioTaper.lock(); if (!ret) { ret = std::make_shared>(); LookupTableFactory::makeAudioTaper(*ret); audioTaper = ret; } return ret; return nullptr; } template std::shared_ptr> ObjectCache::getSinLookup() { std::shared_ptr< LookupTableParams> ret = sinLookupTable.lock(); if (!ret) { ret = std::make_shared>(); std::function f = AudioMath::makeFunc_Sin(); // Used to use 4096, but 512 gives about 92db snr, so let's save memory LookupTable::init(*ret, 512, 0, 1, f); sinLookupTable = ret; } return ret; } template std::shared_ptr> ObjectCache::getExp2() { std::shared_ptr< LookupTableParams> ret = exp2.lock(); if (!ret) { ret = std::make_shared>(); LookupTableFactory::makeExp2(*ret); exp2 = ret; } return ret; } template std::shared_ptr> ObjectCache::getExp2ExtendedLow() { std::shared_ptr< LookupTableParams> ret = exp2ExLow.lock(); if (!ret) { ret = std::make_shared>(); LookupTableFactory::makeExp2ExLow(*ret); exp2ExLow = ret; } return ret; } template std::shared_ptr> ObjectCache::getExp2ExtendedHigh() { std::shared_ptr< LookupTableParams> ret = exp2ExHigh.lock(); if (!ret) { ret = std::make_shared>(); LookupTableFactory::makeExp2ExHigh(*ret); exp2ExHigh = ret; } return ret; } template std::shared_ptr> ObjectCache::getDb2Gain() { std::shared_ptr< LookupTableParams> ret = db2Gain.lock(); if (!ret) { ret = std::make_shared>(); LookupTable::init(*ret, 32, -80, 20, [](double x) { return AudioMath::gainFromDb(x); }); db2Gain = ret; } return ret; } template std::shared_ptr> ObjectCache::getTanh5() { std::shared_ptr< LookupTableParams> ret = tanh5.lock(); if (!ret) { ret = std::make_shared>(); LookupTable::init(*ret, 256, -5, 5, [](double x) { return std::tanh(x); }); tanh5 = ret; } return ret; } /** * Lambda capture two smart pointers to lookup table params, * so lifetime of the lambda control their reft. */ template std::function ObjectCache::getExp2Ex() { std::shared_ptr < LookupTableParams> low = getExp2ExtendedLow(); std::shared_ptr < LookupTableParams> high = getExp2ExtendedHigh(); const T xDivide = (T) LookupTableFactory::exp2ExHighXMin(); return [low, high, xDivide](T x) { auto params = (x < xDivide) ? low : high; return LookupTable::lookup(*params, x, true); }; } template std::shared_ptr> ObjectCache::get6PLPParams(float normalizedFc) { const int div = (int) std::round(1.0 / normalizedFc); if (div == 64) { std::shared_ptr < BiquadParams> ret = lowpass64.lock(); if (!ret) { ret = std::make_shared>(); ButterworthFilterDesigner::designSixPoleLowpass(*ret, normalizedFc); lowpass64 = ret; } return ret; } else if (div == 16) { std::shared_ptr < BiquadParams> ret = lowpass16.lock(); if (!ret) { ret = std::make_shared>(); ButterworthFilterDesigner::designSixPoleLowpass(*ret, normalizedFc); lowpass16 = ret; } return ret; } else if (div == 32) { std::shared_ptr < BiquadParams> ret = lowpass32.lock(); if (!ret) { ret = std::make_shared>(); ButterworthFilterDesigner::designSixPoleLowpass(*ret, normalizedFc); lowpass32 = ret; } return ret; } else { assert(false); } return nullptr; }; // The weak pointers that hold our singletons. template std::weak_ptr< BiquadParams > ObjectCache::lowpass64; template std::weak_ptr< BiquadParams > ObjectCache::lowpass32; template std::weak_ptr< BiquadParams > ObjectCache::lowpass16; template std::weak_ptr> ObjectCache::bipolarAudioTaper; template std::weak_ptr> ObjectCache::audioTaper; template std::weak_ptr> ObjectCache::sinLookupTable; template std::weak_ptr> ObjectCache::exp2; template std::weak_ptr> ObjectCache::exp2ExLow; template std::weak_ptr> ObjectCache::exp2ExHigh; template std::weak_ptr> ObjectCache::db2Gain; template std::weak_ptr> ObjectCache::tanh5; // Explicit instantiation, so we can put implementation into .cpp file template class ObjectCache; template class ObjectCache;