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.

535 lines
12KB

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