You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
5.5KB

  1. #include <assert.h>
  2. #include "AudioMath.h"
  3. #include "ButterworthFilterDesigner.h"
  4. #include "LookupTableFactory.h"
  5. #include "ObjectCache.h"
  6. template <typename T>
  7. std::shared_ptr<LookupTableParams<T>> ObjectCache<T>::getBipolarAudioTaper()
  8. {
  9. std::shared_ptr< LookupTableParams<T>> ret = bipolarAudioTaper.lock();
  10. if (!ret) {
  11. ret = std::make_shared<LookupTableParams<T>>();
  12. LookupTableFactory<T>::makeBipolarAudioTaper(*ret);
  13. bipolarAudioTaper = ret;
  14. }
  15. return ret;
  16. }
  17. template <typename T>
  18. std::shared_ptr<LookupTableParams<T>> ObjectCache<T>::getAudioTaper()
  19. {
  20. std::shared_ptr< LookupTableParams<T>> ret = audioTaper.lock();
  21. if (!ret) {
  22. ret = std::make_shared<LookupTableParams<T>>();
  23. LookupTableFactory<T>::makeAudioTaper(*ret);
  24. audioTaper = ret;
  25. }
  26. return ret;
  27. return nullptr;
  28. }
  29. template <typename T>
  30. std::shared_ptr<LookupTableParams<T>> ObjectCache<T>::getSinLookup()
  31. {
  32. std::shared_ptr< LookupTableParams<T>> ret = sinLookupTable.lock();
  33. if (!ret) {
  34. ret = std::make_shared<LookupTableParams<T>>();
  35. std::function<double(double)> f = AudioMath::makeFunc_Sin();
  36. // Used to use 4096, but 512 gives about 92db snr, so let's save memory
  37. LookupTable<T>::init(*ret, 512, 0, 1, f);
  38. sinLookupTable = ret;
  39. }
  40. return ret;
  41. }
  42. template <typename T>
  43. std::shared_ptr<LookupTableParams<T>> ObjectCache<T>::getExp2()
  44. {
  45. std::shared_ptr< LookupTableParams<T>> ret = exp2.lock();
  46. if (!ret) {
  47. ret = std::make_shared<LookupTableParams<T>>();
  48. LookupTableFactory<T>::makeExp2(*ret);
  49. exp2 = ret;
  50. }
  51. return ret;
  52. }
  53. template <typename T>
  54. std::shared_ptr<LookupTableParams<T>> ObjectCache<T>::getExp2ExtendedLow()
  55. {
  56. std::shared_ptr< LookupTableParams<T>> ret = exp2ExLow.lock();
  57. if (!ret) {
  58. ret = std::make_shared<LookupTableParams<T>>();
  59. LookupTableFactory<T>::makeExp2ExLow(*ret);
  60. exp2ExLow = ret;
  61. }
  62. return ret;
  63. }
  64. template <typename T>
  65. std::shared_ptr<LookupTableParams<T>> ObjectCache<T>::getExp2ExtendedHigh()
  66. {
  67. std::shared_ptr< LookupTableParams<T>> ret = exp2ExHigh.lock();
  68. if (!ret) {
  69. ret = std::make_shared<LookupTableParams<T>>();
  70. LookupTableFactory<T>::makeExp2ExHigh(*ret);
  71. exp2ExHigh = ret;
  72. }
  73. return ret;
  74. }
  75. template <typename T>
  76. std::shared_ptr<LookupTableParams<T>> ObjectCache<T>::getDb2Gain()
  77. {
  78. std::shared_ptr< LookupTableParams<T>> ret = db2Gain.lock();
  79. if (!ret) {
  80. ret = std::make_shared<LookupTableParams<T>>();
  81. LookupTable<T>::init(*ret, 32, -80, 20, [](double x) {
  82. return AudioMath::gainFromDb(x);
  83. });
  84. db2Gain = ret;
  85. }
  86. return ret;
  87. }
  88. template <typename T>
  89. std::shared_ptr<LookupTableParams<T>> ObjectCache<T>::getTanh5()
  90. {
  91. std::shared_ptr< LookupTableParams<T>> ret = tanh5.lock();
  92. if (!ret) {
  93. ret = std::make_shared<LookupTableParams<T>>();
  94. LookupTable<T>::init(*ret, 256, -5, 5, [](double x) {
  95. return std::tanh(x);
  96. });
  97. tanh5 = ret;
  98. }
  99. return ret;
  100. }
  101. /**
  102. * Lambda capture two smart pointers to lookup table params,
  103. * so lifetime of the lambda control their reft.
  104. */
  105. template <typename T>
  106. std::function<T(T)> ObjectCache<T>::getExp2Ex()
  107. {
  108. std::shared_ptr < LookupTableParams<T>> low = getExp2ExtendedLow();
  109. std::shared_ptr < LookupTableParams<T>> high = getExp2ExtendedHigh();
  110. const T xDivide = (T) LookupTableFactory<T>::exp2ExHighXMin();
  111. return [low, high, xDivide](T x) {
  112. auto params = (x < xDivide) ? low : high;
  113. return LookupTable<T>::lookup(*params, x, true);
  114. };
  115. }
  116. template <typename T>
  117. std::shared_ptr<BiquadParams<float, 3>> ObjectCache<T>::get6PLPParams(float normalizedFc)
  118. {
  119. const int div = (int) std::round(1.0 / normalizedFc);
  120. if (div == 64) {
  121. std::shared_ptr < BiquadParams<float, 3>> ret = lowpass64.lock();
  122. if (!ret) {
  123. ret = std::make_shared<BiquadParams<float, 3>>();
  124. ButterworthFilterDesigner<float>::designSixPoleLowpass(*ret, normalizedFc);
  125. lowpass64 = ret;
  126. }
  127. return ret;
  128. } else if (div == 16) {
  129. std::shared_ptr < BiquadParams<float, 3>> ret = lowpass16.lock();
  130. if (!ret) {
  131. ret = std::make_shared<BiquadParams<float, 3>>();
  132. ButterworthFilterDesigner<float>::designSixPoleLowpass(*ret, normalizedFc);
  133. lowpass16 = ret;
  134. }
  135. return ret;
  136. }
  137. else assert(false);
  138. return nullptr;
  139. }
  140. // The weak pointers that hold our singletons.
  141. template <typename T>
  142. std::weak_ptr< BiquadParams<float, 3> > ObjectCache<T>::lowpass64;
  143. template <typename T>
  144. std::weak_ptr< BiquadParams<float, 3> > ObjectCache<T>::lowpass16;
  145. template <typename T>
  146. std::weak_ptr<LookupTableParams<T>> ObjectCache<T>::bipolarAudioTaper;
  147. template <typename T>
  148. std::weak_ptr<LookupTableParams<T>> ObjectCache<T>::audioTaper;
  149. template <typename T>
  150. std::weak_ptr<LookupTableParams<T>> ObjectCache<T>::sinLookupTable;
  151. template <typename T>
  152. std::weak_ptr<LookupTableParams<T>> ObjectCache<T>::exp2;
  153. template <typename T>
  154. std::weak_ptr<LookupTableParams<T>> ObjectCache<T>::exp2ExLow;
  155. template <typename T>
  156. std::weak_ptr<LookupTableParams<T>> ObjectCache<T>::exp2ExHigh;
  157. template <typename T>
  158. std::weak_ptr<LookupTableParams<T>> ObjectCache<T>::db2Gain;
  159. template <typename T>
  160. std::weak_ptr<LookupTableParams<T>> ObjectCache<T>::tanh5;
  161. // Explicit instantiation, so we can put implementation into .cpp file
  162. template class ObjectCache<double>;
  163. template class ObjectCache<float>;