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.

393 lines
9.4KB

  1. /*
  2. Copyright (C) 2006-2011 Nasca Octavian Paul
  3. Author: Nasca Octavian Paul
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of version 2 of the GNU General Public License
  6. as published by the Free Software Foundation.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License (version 2) for more details.
  11. You should have received a copy of the GNU General Public License (version 2)
  12. along with this program; if not, write to the Free Software Foundation,
  13. Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  14. */
  15. #pragma once
  16. #include <vector>
  17. #include <memory>
  18. #include <set>
  19. #include "../JuceLibraryCode/JuceHeader.h"
  20. const String g_plugintitle{ "PaulXStretch 1.2.5" };
  21. using REALTYPE = float;
  22. using floatvector = std::vector<REALTYPE>;
  23. using float2dvector = std::vector<std::vector<float>>;
  24. using float3dvector = std::vector<std::vector<std::vector<float>>>;
  25. template<typename T>
  26. using uptrvec = std::vector<std::unique_ptr<T>>;
  27. template<typename T>
  28. using sptrvec = std::vector<std::shared_ptr<T>>;
  29. template<typename T>
  30. inline std::unique_ptr<T> unique_from_raw(T* ptr)
  31. {
  32. return std::unique_ptr<T>(ptr);
  33. }
  34. template<typename T>
  35. inline String toString(const T& x)
  36. {
  37. return String(x);
  38. }
  39. inline String toString(double x)
  40. {
  41. return String(x,3);
  42. }
  43. template<typename T>
  44. inline String toString(const Range<T>& x)
  45. {
  46. return String(x.getStart()) + " " + String(x.getEnd());
  47. }
  48. template<typename... Args>
  49. inline String formatted(Args... args)
  50. {
  51. String result;
  52. (result << ... << toString(args));
  53. return result;
  54. }
  55. #ifndef USEOLDPLAYCURSOR
  56. #define USEOLDPLAYCURSOR
  57. #endif
  58. #ifndef NULL
  59. #define NULL 0
  60. #endif
  61. const double c_PI = 3.14159265359;
  62. const int g_maxnumoutchans = 32;
  63. #ifndef USE_LUA_SCRIPTING
  64. //#define USE_LUA_SCRIPTING
  65. #endif
  66. template<typename... Args>
  67. inline bool hasProperties(ValueTree src, Args&&... args)
  68. {
  69. if (sizeof...(args) == 0)
  70. return false;
  71. return (src.hasProperty(args) && ...);
  72. }
  73. template<typename... Ts>
  74. inline void storeToTreeProperties(ValueTree dest, UndoManager* uman, juce::Identifier varname, var val, Ts&&... args)
  75. {
  76. dest.setProperty(varname, val, uman);
  77. if constexpr(sizeof...(Ts)>1)
  78. storeToTreeProperties(dest, uman, args...);
  79. }
  80. template<typename T>
  81. inline void storeToTreeProperties(ValueTree dest, UndoManager* uman, juce::Identifier varname, Range<T> x)
  82. {
  83. dest.setProperty(varname+"_start", x.getStart(), uman);
  84. dest.setProperty(varname+"_end", x.getEnd(), uman);
  85. }
  86. inline void storeToTreeProperties(ValueTree dest, UndoManager* uman, AudioParameterFloat* par)
  87. {
  88. if (par) dest.setProperty(par->paramID, (float)*par, uman);
  89. }
  90. inline void storeToTreeProperties(ValueTree dest, UndoManager* uman, AudioParameterBool* par)
  91. {
  92. if (par) dest.setProperty(par->paramID,(bool)*par,uman);
  93. }
  94. inline void storeToTreeProperties(ValueTree dest, UndoManager* uman, AudioParameterInt* par)
  95. {
  96. if (par) dest.setProperty(par->paramID,(int)*par,uman);
  97. }
  98. inline void storeToTreeProperties(ValueTree dest, UndoManager* uman, const Array<AudioProcessorParameter*>& pars,
  99. const std::set<AudioProcessorParameter*>& ignorepars = {})
  100. {
  101. for (auto& e : pars)
  102. {
  103. if (ignorepars.count(e))
  104. continue;
  105. auto parf = dynamic_cast<AudioParameterFloat*>(e);
  106. if (parf != nullptr)
  107. storeToTreeProperties(dest, nullptr, parf);
  108. auto pari = dynamic_cast<AudioParameterInt*>(e);
  109. if (pari != nullptr)
  110. storeToTreeProperties(dest, nullptr, pari);
  111. auto parb = dynamic_cast<AudioParameterBool*>(e);
  112. if (parb != nullptr)
  113. storeToTreeProperties(dest, nullptr, parb);
  114. }
  115. }
  116. template<typename... Ts, typename T>
  117. inline void getFromTreeProperties(ValueTree src, juce::Identifier varname, T& val, Ts&... args)
  118. {
  119. if (src.hasProperty(varname))
  120. val = src.getProperty(varname);
  121. if constexpr(sizeof...(Ts)>1)
  122. getFromTreeProperties(src, args...);
  123. }
  124. template<typename T>
  125. inline void getFromTreeProperties(ValueTree src, juce::Identifier varname, Range<T>& rng)
  126. {
  127. if (hasProperties(src, varname + "_start", varname + "_end"))
  128. {
  129. rng = { src.getProperty(varname + "_start") , src.getProperty(varname + "_end") };
  130. }
  131. else
  132. {
  133. jassert(false);
  134. }
  135. }
  136. template<typename T>
  137. inline void getFromTreeProperties(ValueTree src, T par)
  138. {
  139. static_assert(std::is_base_of<AudioProcessorParameterWithID,typename std::remove_pointer<T>::type>::value,
  140. "T must inherit from AudioProcessorParameterWithID");
  141. if (par!=nullptr && src.hasProperty(par->paramID))
  142. {
  143. *par = src.getProperty(par->paramID);
  144. }
  145. }
  146. inline void getFromTreeProperties(ValueTree src, const Array<AudioProcessorParameter*>& pars)
  147. {
  148. for (auto& e : pars)
  149. {
  150. auto parf = dynamic_cast<AudioParameterFloat*>(e);
  151. if (parf != nullptr && src.hasProperty(parf->paramID))
  152. *parf = src.getProperty(parf->paramID);
  153. auto pari = dynamic_cast<AudioParameterInt*>(e);
  154. if (pari != nullptr && src.hasProperty(pari->paramID))
  155. *pari = src.getProperty(pari->paramID);
  156. auto parb = dynamic_cast<AudioParameterBool*>(e);
  157. if (parb != nullptr && src.hasProperty(parb->paramID))
  158. *parb = src.getProperty(parb->paramID);
  159. }
  160. }
  161. template<typename F>
  162. inline void timeCall(String msgprefix,F&& f)
  163. {
  164. double t0 = Time::getMillisecondCounterHiRes();
  165. f();
  166. double t1 = Time::getMillisecondCounterHiRes();
  167. Logger::writeToLog(formatted(msgprefix, " took " , t1 - t0 , " ms"));
  168. }
  169. template<typename Cont, typename T>
  170. inline void fill_container(Cont& c, const T& x)
  171. {
  172. std::fill(std::begin(c), std::end(c), x);
  173. }
  174. template<typename T>
  175. class CircularBuffer final
  176. {
  177. public:
  178. CircularBuffer(int size)
  179. {
  180. m_buf.resize(size);
  181. }
  182. void clear()
  183. {
  184. m_avail = 0;
  185. m_readpos = 0;
  186. m_writepos = 0;
  187. fill_container(m_buf, T());
  188. }
  189. void push(T x)
  190. {
  191. m_buf[m_writepos] = x;
  192. ++m_writepos;
  193. ++m_avail;
  194. if (m_writepos >= m_buf.size())
  195. m_writepos = 0;
  196. }
  197. T get()
  198. {
  199. jassert(m_avail > 0);
  200. T x = m_buf[m_readpos];
  201. ++m_readpos;
  202. --m_avail;
  203. if (m_readpos >= m_buf.size())
  204. m_readpos = 0;
  205. return x;
  206. }
  207. int available() { return m_avail; }
  208. int getToBuf(T* buf, int len)
  209. {
  210. jassert(m_avail > 0);
  211. if (len > m_avail)
  212. len = m_avail;
  213. for (int i = 0; i < len; ++i)
  214. buf[i] = get();
  215. return len;
  216. }
  217. int getFromBuf(T* buf, int len)
  218. {
  219. for (int i = 0; i < len; ++i)
  220. push(buf[i]);
  221. return len;
  222. }
  223. int getSize() { return (int)m_buf.size(); }
  224. void resize(int size)
  225. {
  226. m_avail = 0;
  227. m_readpos = 0;
  228. m_writepos = 0;
  229. m_buf.resize(size);
  230. }
  231. private:
  232. int m_writepos = 0;
  233. int m_readpos = 0;
  234. int m_avail = 0;
  235. std::vector<T> m_buf;
  236. };
  237. template<typename T, typename F>
  238. inline void callGUI(T* ap, F&& f, bool async)
  239. {
  240. auto ed = dynamic_cast<typename T::EditorType*>(ap->getActiveEditor());
  241. if (ed)
  242. {
  243. if (async == false)
  244. f(ed);
  245. else
  246. MessageManager::callAsync([ed, f]() { f(ed); });
  247. }
  248. }
  249. inline String secondsToString2(double secs)
  250. {
  251. RelativeTime rt(secs);
  252. String result;
  253. result.preallocateBytes(32);
  254. bool empty = true;
  255. if ((int)rt.inHours()>0)
  256. result << String((int)rt.inHours() % 24).paddedLeft('0', empty ? 1 : 2) << ':';
  257. result << String((int)rt.inMinutes() % 60).paddedLeft('0', 2) << ':';
  258. result << String((int)rt.inSeconds() % 60).paddedLeft('0', 2);
  259. auto millis = (int)rt.inMilliseconds() % 1000;
  260. if (millis > 0)
  261. result << '.' << String(millis).paddedLeft('0', 3);
  262. return result.trimEnd();
  263. }
  264. inline String secondsToString(double seconds)
  265. {
  266. int64_t durintseconds = seconds;
  267. int64_t durintminutes = seconds / 60.0;
  268. int64_t durinthours = seconds / 3600.0;
  269. int64_t durintdays = seconds / (3600 * 24.0);
  270. String timestring;
  271. if (durintminutes < 1)
  272. timestring = String(seconds, 3) + " seconds";
  273. if (durintminutes >= 1 && durinthours < 1)
  274. timestring = String(durintminutes) + " mins " + String(durintseconds % 60) + " secs";
  275. if (durinthours >= 1 && durintdays < 1)
  276. timestring = String(durinthours) + " hours " + String(durintminutes % 60) + " mins " + String(durintseconds % 60) + " secs";
  277. if (durintdays >= 1)
  278. timestring = String(durintdays) + " days " + String(durinthours % 24) + " hours " +
  279. String(durintminutes % 60) + " mins ";
  280. return timestring;
  281. }
  282. inline void toggleBool(bool& b)
  283. {
  284. b = !b;
  285. }
  286. inline void toggleBool(AudioParameterBool* b)
  287. {
  288. *b = !(*b);
  289. }
  290. template<typename T>
  291. inline bool is_in_range(T val, T start, T end)
  292. {
  293. return val >= start && val <= end;
  294. }
  295. inline void sanitizeTimeRange(double& t0, double& t1)
  296. {
  297. if (t0 > t1)
  298. std::swap(t0, t1);
  299. if (t1 - t0 < 0.001)
  300. t1 = t0 + 0.001;
  301. }
  302. inline double fractpart(double x) { return x - (int)x; };
  303. class SignalSmoother
  304. {
  305. public:
  306. SignalSmoother()
  307. {
  308. m_a = 0.5;
  309. m_slope = m_a;
  310. m_b = 1.0 - m_a;
  311. m_z = 0;
  312. }
  313. inline double process(double in)
  314. {
  315. double result = in + m_a * (m_z - in);
  316. m_z = result;
  317. return result;
  318. }
  319. void setSlope(double x, double sr)
  320. {
  321. if (x != m_slope || sr != m_sr)
  322. {
  323. m_slope = x;
  324. m_sr = sr;
  325. double srCompensate = srCompensate = sr / 100.0;
  326. double compensated_a = powf(x, (1.0 / srCompensate));
  327. m_a = compensated_a;
  328. m_b = 1.0 - m_a;
  329. }
  330. }
  331. double getSlope() const { return m_slope; }
  332. double getSamplerate() const { return m_sr; }
  333. private:
  334. double m_a, m_b, m_z;
  335. double m_slope;
  336. double m_sr = 0.0;
  337. };
  338. namespace XenUtils
  339. {
  340. template<typename T, typename... Args>
  341. inline std::unique_ptr<T> makeAddAndMakeVisible(Component& parent, Args&&... args)
  342. {
  343. auto temp = std::make_unique<T>(args...);
  344. parent.addAndMakeVisible(temp.get());
  345. return std::move(temp);
  346. }
  347. }