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.

202 lines
5.9KB

  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. } else if (div == 32) {
  137. std::shared_ptr < BiquadParams<float, 3>> ret = lowpass32.lock();
  138. if (!ret) {
  139. ret = std::make_shared<BiquadParams<float, 3>>();
  140. ButterworthFilterDesigner<float>::designSixPoleLowpass(*ret, normalizedFc);
  141. lowpass32 = ret;
  142. }
  143. return ret;
  144. } else {
  145. assert(false);
  146. }
  147. return nullptr;
  148. };
  149. // The weak pointers that hold our singletons.
  150. template <typename T>
  151. std::weak_ptr< BiquadParams<float, 3> > ObjectCache<T>::lowpass64;
  152. template <typename T>
  153. std::weak_ptr< BiquadParams<float, 3> > ObjectCache<T>::lowpass32;
  154. template <typename T>
  155. std::weak_ptr< BiquadParams<float, 3> > ObjectCache<T>::lowpass16;
  156. template <typename T>
  157. std::weak_ptr<LookupTableParams<T>> ObjectCache<T>::bipolarAudioTaper;
  158. template <typename T>
  159. std::weak_ptr<LookupTableParams<T>> ObjectCache<T>::audioTaper;
  160. template <typename T>
  161. std::weak_ptr<LookupTableParams<T>> ObjectCache<T>::sinLookupTable;
  162. template <typename T>
  163. std::weak_ptr<LookupTableParams<T>> ObjectCache<T>::exp2;
  164. template <typename T>
  165. std::weak_ptr<LookupTableParams<T>> ObjectCache<T>::exp2ExLow;
  166. template <typename T>
  167. std::weak_ptr<LookupTableParams<T>> ObjectCache<T>::exp2ExHigh;
  168. template <typename T>
  169. std::weak_ptr<LookupTableParams<T>> ObjectCache<T>::db2Gain;
  170. template <typename T>
  171. std::weak_ptr<LookupTableParams<T>> ObjectCache<T>::tanh5;
  172. // Explicit instantiation, so we can put implementation into .cpp file
  173. template class ObjectCache<double>;
  174. template class ObjectCache<float>;