Audio plugin host https://kx.studio/carla
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.

529 lines
11KB

  1. /*
  2. * Carla common utils
  3. * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the COPYING file
  16. */
  17. #ifndef __CARLA_UTILS_HPP__
  18. #define __CARLA_UTILS_HPP__
  19. #include "carla_defines.hpp"
  20. #include <cstdio>
  21. #include <cstdlib>
  22. #include <cstring>
  23. #include <pthread.h>
  24. #if defined(Q_OS_HAIKU)
  25. # include <kernel/OS.h>
  26. #elif defined(Q_OS_LINUX)
  27. # include <sys/prctl.h>
  28. # include <linux/prctl.h>
  29. #endif
  30. // -------------------------------------------------
  31. // carla_assert*
  32. static inline
  33. void carla_assert(const char* const assertion, const char* const file, const int line)
  34. {
  35. qCritical("Carla assertion failure: \"%s\" in file %s, line %i", assertion, file, line);
  36. }
  37. static inline
  38. void carla_assert_int(const char* const assertion, const char* const file, const int line, const int value)
  39. {
  40. qCritical("Carla assertion failure: \"%s\" in file %s, line %i, value %i", assertion, file, line, value);
  41. }
  42. // -------------------------------------------------
  43. // carla_*sleep (carla_usleep not possible in Windows)
  44. static inline
  45. void carla_sleep(const unsigned int secs)
  46. {
  47. CARLA_ASSERT(secs > 0);
  48. #ifdef Q_OS_WIN
  49. Sleep(secs * 1000);
  50. #else
  51. sleep(secs);
  52. #endif
  53. }
  54. static inline
  55. void carla_msleep(const unsigned int msecs)
  56. {
  57. CARLA_ASSERT(msecs > 0);
  58. #ifdef Q_OS_WIN
  59. Sleep(msecs);
  60. #else
  61. usleep(msecs * 1000);
  62. #endif
  63. }
  64. static inline
  65. void carla_usleep(const unsigned int usecs)
  66. {
  67. CARLA_ASSERT(usecs > 0);
  68. #ifdef Q_OS_WIN
  69. Sleep(usecs / 1000);
  70. #else
  71. usleep(usecs);
  72. #endif
  73. }
  74. // -------------------------------------------------
  75. // carla_setenv
  76. static inline
  77. void carla_setenv(const char* const key, const char* const value)
  78. {
  79. CARLA_ASSERT(key);
  80. CARLA_ASSERT(value);
  81. #ifdef Q_OS_WIN
  82. SetEnvironmentVariableA(key, value);
  83. #else
  84. setenv(key, value, 1);
  85. #endif
  86. }
  87. // -------------------------------------------------
  88. // carla_setprocname (not available on all platforms)
  89. static inline
  90. void carla_setprocname(const char* const name)
  91. {
  92. CARLA_ASSERT(name);
  93. #if defined(Q_OS_HAIKU)
  94. if ((thread_id this_thread = find_thread(nullptr)) != B_NAME_NOT_FOUND)
  95. rename_thread(this_thread, name);
  96. #elif defined(Q_OS_LINUX)
  97. prctl(PR_SET_NAME, name);
  98. #else
  99. qWarning("carla_setprocname(\"%s\") - unsupported on this platform", name);
  100. #endif
  101. }
  102. // -------------------------------------------------
  103. // math functions
  104. template<typename T>
  105. static inline
  106. const T& carla_min(const T& v1, const T& v2, const T& min)
  107. {
  108. return ((v1 < min || v2 < min) ? min : (v1 < v2 ? v1 : v2));
  109. }
  110. template<typename T>
  111. static inline
  112. void carla_fill(T* data, const unsigned int size, const T v)
  113. {
  114. CARLA_ASSERT(data);
  115. CARLA_ASSERT(size > 0);
  116. for (unsigned int i=0; i < size; i++)
  117. *data++ = v;
  118. }
  119. static inline
  120. void carla_zeroDouble(double* data, const unsigned size)
  121. {
  122. carla_fill<double>(data, size, 0.0);
  123. }
  124. static inline
  125. void carla_zeroFloat(float* data, const unsigned size)
  126. {
  127. carla_fill<float>(data, size, 0.0f);
  128. }
  129. // -------------------------------------------------
  130. // other misc functions
  131. static inline
  132. const char* bool2str(const bool yesNo)
  133. {
  134. return yesNo ? "true" : "false";
  135. }
  136. static inline
  137. void pass() {}
  138. // -------------------------------------------------
  139. // CarlaMutex class
  140. class CarlaMutex
  141. {
  142. public:
  143. CarlaMutex()
  144. : pmutex(PTHREAD_MUTEX_INITIALIZER)
  145. {
  146. pthread_mutex_init(&pmutex, nullptr);
  147. }
  148. ~CarlaMutex()
  149. {
  150. pthread_mutex_destroy(&pmutex);
  151. }
  152. bool lock()
  153. {
  154. return (pthread_mutex_lock(&pmutex) == 0);
  155. }
  156. bool tryLock()
  157. {
  158. return (pthread_mutex_trylock(&pmutex) == 0);
  159. }
  160. bool unlock()
  161. {
  162. return (pthread_mutex_unlock(&pmutex) == 0);
  163. }
  164. class ScopedLocker
  165. {
  166. public:
  167. ScopedLocker(CarlaMutex* const mutex_)
  168. : mutex(mutex_)
  169. {
  170. mutex->lock();
  171. }
  172. ~ScopedLocker()
  173. {
  174. mutex->unlock();
  175. }
  176. private:
  177. CarlaMutex* const mutex;
  178. };
  179. private:
  180. pthread_mutex_t pmutex;
  181. };
  182. // -------------------------------------------------
  183. // CarlaString class
  184. class CarlaString
  185. {
  186. public:
  187. // ---------------------------------------------
  188. // constructors (no explicit conversions allowed)
  189. explicit CarlaString()
  190. {
  191. buffer = ::strdup("");
  192. }
  193. explicit CarlaString(char* const strBuf)
  194. {
  195. buffer = ::strdup(strBuf ? strBuf : "");
  196. }
  197. explicit CarlaString(const char* const strBuf)
  198. {
  199. buffer = ::strdup(strBuf ? strBuf : "");
  200. }
  201. explicit CarlaString(const int value)
  202. {
  203. const size_t strBufSize = ::abs(value/10) + 3;
  204. char strBuf[strBufSize];
  205. ::snprintf(strBuf, strBufSize, "%d", value);
  206. buffer = ::strdup(strBuf);
  207. }
  208. explicit CarlaString(const unsigned int value, const bool hexadecimal = false)
  209. {
  210. const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0);
  211. char strBuf[strBufSize];
  212. ::snprintf(strBuf, strBufSize, hexadecimal ? "%u" : "0x%x", value);
  213. buffer = ::strdup(strBuf);
  214. }
  215. explicit CarlaString(const long int value)
  216. {
  217. const size_t strBufSize = ::labs(value/10) + 3;
  218. char strBuf[strBufSize];
  219. ::snprintf(strBuf, strBufSize, "%ld", value);
  220. buffer = ::strdup(strBuf);
  221. }
  222. explicit CarlaString(const unsigned long int value, const bool hexadecimal = false)
  223. {
  224. const size_t strBufSize = value/10 + 2 + (hexadecimal ? 2 : 0);
  225. char strBuf[strBufSize];
  226. ::snprintf(strBuf, strBufSize, hexadecimal ? "%lu" : "0x%lx", value);
  227. buffer = ::strdup(strBuf);
  228. }
  229. explicit CarlaString(const float value)
  230. {
  231. char strBuf[0xff];
  232. ::snprintf(strBuf, 0xff, "%f", value);
  233. buffer = ::strdup(strBuf);
  234. }
  235. explicit CarlaString(const double value)
  236. {
  237. char strBuf[0xff];
  238. ::snprintf(strBuf, 0xff, "%g", value);
  239. buffer = ::strdup(strBuf);
  240. }
  241. // ---------------------------------------------
  242. // non-explicit constructor
  243. CarlaString(const CarlaString& str)
  244. {
  245. buffer = ::strdup(str.buffer);
  246. }
  247. // ---------------------------------------------
  248. // deconstructor
  249. ~CarlaString()
  250. {
  251. CARLA_ASSERT(buffer);
  252. ::free(buffer);
  253. }
  254. // ---------------------------------------------
  255. // public methods
  256. size_t length() const
  257. {
  258. return ::strlen(buffer);
  259. }
  260. bool isEmpty() const
  261. {
  262. return (*buffer == 0);
  263. }
  264. bool isNotEmpty() const
  265. {
  266. return (*buffer != 0);
  267. }
  268. bool contains(const char* const strBuf) const
  269. {
  270. if (! strBuf)
  271. return false;
  272. if (*strBuf == 0)
  273. return false;
  274. size_t thisLen = ::strlen(buffer);
  275. size_t thatLen = ::strlen(strBuf)-1;
  276. for (size_t i=0, j=0; i < thisLen; i++)
  277. {
  278. if (buffer[i] == strBuf[j])
  279. j++;
  280. else
  281. j = 0;
  282. if (j == thatLen)
  283. return true;
  284. }
  285. return false;
  286. }
  287. bool contains(const CarlaString& str) const
  288. {
  289. return contains(str.buffer);
  290. }
  291. bool isDigit(const size_t pos) const
  292. {
  293. if (pos >= length())
  294. return false;
  295. return (buffer[pos] >= '0' && buffer[pos] <= '9');
  296. }
  297. void clear()
  298. {
  299. truncate(0);
  300. }
  301. void replace(const char before, const char after)
  302. {
  303. for (size_t i=0, len = ::strlen(buffer); i < len; i++)
  304. {
  305. if (buffer[i] == before)
  306. buffer[i] = after;
  307. }
  308. }
  309. void truncate(const unsigned int n)
  310. {
  311. for (size_t i=n, len = ::strlen(buffer); i < len; i++)
  312. buffer[i] = 0;
  313. }
  314. void toBasic()
  315. {
  316. for (size_t i=0, len = ::strlen(buffer); i < len; i++)
  317. {
  318. if (buffer[i] >= '0' && buffer[i] <= '9')
  319. continue;
  320. if (buffer[i] >= 'A' && buffer[i] <= 'Z')
  321. continue;
  322. if (buffer[i] >= 'a' && buffer[i] <= 'z')
  323. continue;
  324. if (buffer[i] == '_')
  325. continue;
  326. buffer[i] = '_';
  327. }
  328. }
  329. void toLower()
  330. {
  331. for (size_t i=0, len = ::strlen(buffer); i < len; i++)
  332. {
  333. if (buffer[i] >= 'A' && buffer[i] <= 'Z')
  334. buffer[i] += 32;
  335. }
  336. }
  337. void toUpper()
  338. {
  339. for (size_t i=0, len = ::strlen(buffer); i < len; i++)
  340. {
  341. if (buffer[i] >= 'a' && buffer[i] <= 'z')
  342. buffer[i] -= 32;
  343. }
  344. }
  345. // ---------------------------------------------
  346. // public operators
  347. operator const char*() const
  348. {
  349. return buffer;
  350. }
  351. char& operator[](const unsigned int pos)
  352. {
  353. return buffer[pos];
  354. }
  355. bool operator==(const char* const strBuf) const
  356. {
  357. return (strBuf && ::strcmp(buffer, strBuf) == 0);
  358. }
  359. bool operator==(const CarlaString& str) const
  360. {
  361. return operator==(str.buffer);
  362. }
  363. bool operator!=(const char* const strBuf) const
  364. {
  365. return !operator==(strBuf);
  366. }
  367. bool operator!=(const CarlaString& str) const
  368. {
  369. return !operator==(str.buffer);
  370. }
  371. CarlaString& operator=(const char* const strBuf)
  372. {
  373. ::free(buffer);
  374. buffer = ::strdup(strBuf ? strBuf : "");
  375. return *this;
  376. }
  377. CarlaString& operator=(const CarlaString& str)
  378. {
  379. return operator=(str.buffer);
  380. }
  381. CarlaString& operator+=(const char* const strBuf)
  382. {
  383. const size_t newBufSize = ::strlen(buffer) + (strBuf ? ::strlen(strBuf) : 0) + 1;
  384. char newBuf[newBufSize];
  385. ::strcpy(newBuf, buffer);
  386. ::strcat(newBuf, strBuf);
  387. ::free(buffer);
  388. buffer = ::strdup(newBuf);
  389. return *this;
  390. }
  391. CarlaString& operator+=(const CarlaString& str)
  392. {
  393. return operator+=(str.buffer);
  394. }
  395. CarlaString operator+(const char* const strBuf)
  396. {
  397. const size_t newBufSize = ::strlen(buffer) + (strBuf ? ::strlen(strBuf) : 0) + 1;
  398. char newBuf[newBufSize];
  399. ::strcpy(newBuf, buffer);
  400. ::strcat(newBuf, strBuf);
  401. return CarlaString(newBuf);
  402. }
  403. CarlaString operator+(const CarlaString& str)
  404. {
  405. return operator+(str.buffer);
  406. }
  407. // ---------------------------------------------
  408. private:
  409. char* buffer;
  410. };
  411. static inline
  412. CarlaString operator+(const char* const strBufBefore, const CarlaString& strAfter)
  413. {
  414. const char* const strBufAfter = (const char*)strAfter;
  415. const size_t newBufSize = (strBufBefore ? ::strlen(strBufBefore) : 0) + ::strlen(strBufAfter) + 1;
  416. char newBuf[newBufSize];
  417. ::strcpy(newBuf, strBufBefore);
  418. ::strcat(newBuf, strBufAfter);
  419. return CarlaString(newBuf);
  420. }
  421. // -------------------------------------------------
  422. #endif // __CARLA_UTILS_HPP__