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.

624 lines
15KB

  1. /*
  2. * Carla common utils
  3. * Copyright (C) 2011-2024 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or 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 doc/GPL.txt file.
  16. */
  17. #ifndef CARLA_UTILS_HPP_INCLUDED
  18. #define CARLA_UTILS_HPP_INCLUDED
  19. #include "CarlaDefines.h"
  20. #include <cassert>
  21. #include <cstdarg>
  22. #include <cstdio>
  23. #include <cstdlib>
  24. #include <cstring>
  25. #ifdef CARLA_PROPER_CPP11_SUPPORT
  26. # include <cxxabi.h>
  27. # include <cstdint>
  28. #else
  29. # include <stdint.h>
  30. #endif
  31. #ifdef CARLA_OS_WIN
  32. # ifndef NOMINMAX
  33. # define NOMINMAX
  34. # endif
  35. # define WIN32_LEAN_AND_MEAN 1
  36. # include <winsock2.h>
  37. # include <windows.h>
  38. #else
  39. # include <unistd.h>
  40. #endif
  41. // --------------------------------------------------------------------------------------------------------------------
  42. // misc functions
  43. /*
  44. * Return "true" or "false" according to yesNo.
  45. */
  46. static inline
  47. const char* bool2str(const bool yesNo) noexcept
  48. {
  49. return yesNo ? "true" : "false";
  50. }
  51. /*
  52. * Set a string as empty/null.
  53. */
  54. static inline
  55. void nullStrBuf(char* const strBuf) noexcept
  56. {
  57. strBuf[0] = '\0';
  58. }
  59. /*
  60. * Dummy function.
  61. */
  62. static inline
  63. void pass() noexcept {}
  64. // --------------------------------------------------------------------------------------------------------------------
  65. // string print functions
  66. /*
  67. * Internal noexcept-safe fopen function.
  68. */
  69. static inline
  70. FILE* __carla_fopen(const char* const filename, FILE* const fallback) noexcept
  71. {
  72. #ifdef CARLA_OS_LINUX
  73. if (std::getenv("CARLA_CAPTURE_CONSOLE_OUTPUT") == nullptr)
  74. return fallback;
  75. FILE* ret = nullptr;
  76. try {
  77. ret = std::fopen(filename, "a+");
  78. } CARLA_CATCH_UNWIND catch (...) {}
  79. if (ret == nullptr)
  80. ret = fallback;
  81. return ret;
  82. #else
  83. return fallback;
  84. // unused
  85. (void)filename;
  86. #endif
  87. }
  88. /*
  89. * Print a string to stdout with newline (gray color).
  90. * Does nothing if DEBUG is not defined.
  91. */
  92. #ifndef DEBUG
  93. # define carla_debug(...)
  94. #else
  95. static inline
  96. void carla_debug(const char* const fmt, ...) noexcept
  97. {
  98. static FILE* const output = __carla_fopen("/tmp/carla.debug.log", stdout);
  99. try {
  100. ::va_list args;
  101. ::va_start(args, fmt);
  102. if (output == stdout)
  103. {
  104. #ifdef CARLA_OS_MAC
  105. std::fprintf(output, "\x1b[37;1m[carla] ");
  106. #else
  107. std::fprintf(output, "\x1b[30;1m[carla] ");
  108. #endif
  109. std::vfprintf(output, fmt, args);
  110. std::fprintf(output, "\x1b[0m\n");
  111. }
  112. else
  113. {
  114. std::fprintf(output, "[carla] ");
  115. std::vfprintf(output, fmt, args);
  116. std::fprintf(output, "\n");
  117. }
  118. std::fflush(output);
  119. ::va_end(args);
  120. } CARLA_CATCH_UNWIND catch (...) {}
  121. }
  122. #endif
  123. /*
  124. * Print a string to stdout with newline.
  125. */
  126. static inline
  127. void carla_stdout(const char* const fmt, ...) noexcept
  128. {
  129. static FILE* const output = __carla_fopen("/tmp/carla.stdout.log", stdout);
  130. try {
  131. ::va_list args;
  132. ::va_start(args, fmt);
  133. std::fprintf(output, "[carla] ");
  134. std::vfprintf(output, fmt, args);
  135. std::fprintf(output, "\n");
  136. #ifndef DEBUG
  137. if (output != stdout)
  138. #endif
  139. std::fflush(output);
  140. ::va_end(args);
  141. } CARLA_CATCH_UNWIND catch (...) {}
  142. }
  143. /*
  144. * Print a string to stderr with newline.
  145. */
  146. static inline
  147. void carla_stderr(const char* const fmt, ...) noexcept
  148. {
  149. static FILE* const output = __carla_fopen("/tmp/carla.stderr.log", stderr);
  150. try {
  151. ::va_list args;
  152. ::va_start(args, fmt);
  153. std::fprintf(output, "[carla] ");
  154. std::vfprintf(output, fmt, args);
  155. std::fprintf(output, "\n");
  156. #ifndef DEBUG
  157. if (output != stderr)
  158. #endif
  159. std::fflush(output);
  160. ::va_end(args);
  161. } CARLA_CATCH_UNWIND catch (...) {}
  162. }
  163. /*
  164. * Print a string to stderr with newline (red color).
  165. */
  166. static inline
  167. void carla_stderr2(const char* const fmt, ...) noexcept
  168. {
  169. static FILE* const output = __carla_fopen("/tmp/carla.stderr2.log", stderr);
  170. try {
  171. ::va_list args;
  172. ::va_start(args, fmt);
  173. if (output == stderr)
  174. {
  175. std::fprintf(output, "\x1b[31m[carla] ");
  176. std::vfprintf(output, fmt, args);
  177. std::fprintf(output, "\x1b[0m\n");
  178. }
  179. else
  180. {
  181. std::fprintf(output, "[carla] ");
  182. std::vfprintf(output, fmt, args);
  183. std::fprintf(output, "\n");
  184. }
  185. std::fflush(output);
  186. ::va_end(args);
  187. } CARLA_CATCH_UNWIND catch (...) {}
  188. }
  189. // --------------------------------------------------------------------------------------------------------------------
  190. // carla_safe_assert*
  191. /*
  192. * Print a safe assertion error message.
  193. */
  194. static inline
  195. void carla_safe_assert(const char* const assertion, const char* const file, const int line) noexcept
  196. {
  197. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i", assertion, file, line);
  198. }
  199. /*
  200. * Print a safe assertion error message, with 1 extra signed integer value.
  201. */
  202. static inline
  203. void carla_safe_assert_int(const char* const assertion, const char* const file,
  204. const int line, const int value) noexcept
  205. {
  206. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, value %i", assertion, file, line, value);
  207. }
  208. /*
  209. * Print a safe assertion error message, with 1 extra unsigned integer value.
  210. */
  211. static inline
  212. void carla_safe_assert_uint(const char* const assertion, const char* const file,
  213. const int line, const uint value) noexcept
  214. {
  215. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, value %u", assertion, file, line, value);
  216. }
  217. /*
  218. * Print a safe assertion error message, with 2 extra signed integer values.
  219. */
  220. static inline
  221. void carla_safe_assert_int2(const char* const assertion, const char* const file,
  222. const int line, const int v1, const int v2) noexcept
  223. {
  224. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, v1 %i, v2 %i", assertion, file, line, v1, v2);
  225. }
  226. /*
  227. * Print a safe assertion error message, with 2 extra unsigned integer values.
  228. */
  229. static inline
  230. void carla_safe_assert_uint2(const char* const assertion, const char* const file,
  231. const int line, const uint v1, const uint v2) noexcept
  232. {
  233. carla_stderr2("Carla assertion failure: \"%s\" in file %s, line %i, v1 %u, v2 %u", assertion, file, line, v1, v2);
  234. }
  235. /*
  236. * Print a safe assertion error message, with a custom error message.
  237. */
  238. static inline
  239. void carla_custom_safe_assert(const char* const message,
  240. const char* const assertion, const char* const file, const int line) noexcept
  241. {
  242. carla_stderr2("Carla assertion failure: %s, condition \"%s\" in file %s, line %i", message, assertion, file, line);
  243. }
  244. // --------------------------------------------------------------------------------------------------------------------
  245. // carla_safe_exception*
  246. /*
  247. * Print a safe exception error message.
  248. */
  249. static inline
  250. void carla_safe_exception(const char* const exception, const char* const file, const int line) noexcept
  251. {
  252. carla_stderr2("Carla exception caught: \"%s\" in file %s, line %i", exception, file, line);
  253. }
  254. // --------------------------------------------------------------------------------------------------------------------
  255. // carla_*sleep
  256. /*
  257. * Sleep for 'secs' seconds.
  258. */
  259. static inline
  260. void carla_sleep(const uint secs) noexcept
  261. {
  262. CARLA_SAFE_ASSERT_RETURN(secs > 0,);
  263. try {
  264. #ifdef CARLA_OS_WIN
  265. ::Sleep(secs * 1000);
  266. #else
  267. ::sleep(secs);
  268. #endif
  269. } CARLA_SAFE_EXCEPTION("carla_sleep");
  270. }
  271. /*
  272. * Sleep for 'msecs' milliseconds.
  273. */
  274. static inline
  275. void carla_msleep(const uint msecs) noexcept
  276. {
  277. CARLA_SAFE_ASSERT_RETURN(msecs > 0,);
  278. try {
  279. #ifdef CARLA_OS_WIN
  280. ::Sleep(msecs);
  281. #else
  282. ::usleep(msecs * 1000);
  283. #endif
  284. } CARLA_SAFE_EXCEPTION("carla_msleep");
  285. }
  286. // --------------------------------------------------------------------------------------------------------------------
  287. // carla_setenv
  288. /*
  289. * Set environment variable 'key' to 'value'.
  290. */
  291. static inline
  292. void carla_setenv(const char* const key, const char* const value) noexcept
  293. {
  294. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  295. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  296. #ifdef CARLA_OS_WIN
  297. try {
  298. ::SetEnvironmentVariableA(key, value);
  299. } CARLA_SAFE_EXCEPTION("carla_setenv");
  300. #else
  301. ::setenv(key, value, 1);
  302. #endif
  303. }
  304. /*
  305. * Unset environment variable 'key'.
  306. */
  307. static inline
  308. void carla_unsetenv(const char* const key) noexcept
  309. {
  310. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  311. #ifdef CARLA_OS_WIN
  312. try {
  313. ::SetEnvironmentVariableA(key, nullptr);
  314. } CARLA_SAFE_EXCEPTION("carla_unsetenv");
  315. #else
  316. ::unsetenv(key);
  317. #endif
  318. }
  319. // --------------------------------------------------------------------------------------------------------------------
  320. // carla_strdup
  321. /*
  322. * Custom 'strdup' function.
  323. * Returned value is always valid, and must be freed with "delete[] var".
  324. * May throw.
  325. */
  326. static inline
  327. const char* carla_strdup(const char* const strBuf)
  328. {
  329. CARLA_SAFE_ASSERT(strBuf != nullptr);
  330. const std::size_t bufferLen = (strBuf != nullptr) ? std::strlen(strBuf) : 0;
  331. char* const buffer = new char[bufferLen+1];
  332. if (bufferLen > 0)
  333. std::memcpy(buffer, strBuf, bufferLen);
  334. buffer[bufferLen] = '\0';
  335. return buffer;
  336. }
  337. /*
  338. * Custom 'strdup' function.
  339. * Calls "std::free(strBuf)".
  340. * Returned value is always valid, and must be freed with "delete[] var".
  341. * May throw.
  342. */
  343. static inline
  344. const char* carla_strdup_free(char* const strBuf)
  345. {
  346. const char* const buffer(carla_strdup(strBuf));
  347. std::free(strBuf);
  348. return buffer;
  349. }
  350. /*
  351. * Custom 'strdup' function, safe version.
  352. * Returned value may be null. It must be freed with "delete[] var".
  353. */
  354. static inline
  355. const char* carla_strdup_safe(const char* const strBuf) noexcept
  356. {
  357. CARLA_SAFE_ASSERT_RETURN(strBuf != nullptr, nullptr);
  358. const std::size_t bufferLen = std::strlen(strBuf);
  359. char* buffer;
  360. try {
  361. buffer = new char[bufferLen+1];
  362. } CARLA_SAFE_EXCEPTION_RETURN("carla_strdup_safe", nullptr);
  363. if (bufferLen > 0)
  364. std::memcpy(buffer, strBuf, bufferLen);
  365. buffer[bufferLen] = '\0';
  366. return buffer;
  367. }
  368. // --------------------------------------------------------------------------------------------------------------------
  369. // memory functions
  370. /*
  371. * Add array values to another array.
  372. */
  373. template<typename T>
  374. static inline
  375. void carla_add(T dest[], const T src[], const std::size_t count) noexcept
  376. {
  377. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  378. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  379. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  380. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  381. for (std::size_t i=0; i<count; ++i)
  382. dest[i] += src[i];
  383. }
  384. /*
  385. * Add array values to another array, with a multiplication factor.
  386. */
  387. template<typename T>
  388. static inline
  389. void carla_addWithMultiply(T dest[], const T src[], const T& multiplier, const std::size_t count) noexcept
  390. {
  391. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  392. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  393. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  394. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  395. for (std::size_t i=0; i<count; ++i)
  396. dest[i] += src[i] * multiplier;
  397. }
  398. /*
  399. * Copy array values to another array.
  400. */
  401. template<typename T>
  402. static inline
  403. void carla_copy(T dest[], const T src[], const std::size_t count) noexcept
  404. {
  405. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  406. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  407. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  408. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  409. std::memcpy(dest, src, count*sizeof(T));
  410. }
  411. /*
  412. * Copy array values to another array, with a multiplication factor.
  413. */
  414. template<typename T>
  415. static inline
  416. void carla_copyWithMultiply(T dest[], const T src[], const T& multiplier, const std::size_t count) noexcept
  417. {
  418. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  419. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  420. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  421. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  422. for (std::size_t i=0; i<count; ++i)
  423. dest[i] = src[i] * multiplier;
  424. }
  425. /*
  426. * Fill an array with a fixed value.
  427. */
  428. template<typename T>
  429. static inline
  430. void carla_fill(T data[], const T& value, const std::size_t count) noexcept
  431. {
  432. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  433. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  434. if (value == 0)
  435. {
  436. std::memset(data, 0, count*sizeof(T));
  437. }
  438. else
  439. {
  440. for (std::size_t i=0; i<count; ++i)
  441. data[i] = value;
  442. }
  443. }
  444. /*
  445. * Multiply an array with a fixed value.
  446. */
  447. template<typename T>
  448. static inline
  449. void carla_multiply(T data[], const T& multiplier, const std::size_t count) noexcept
  450. {
  451. CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
  452. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  453. if (multiplier == 0)
  454. {
  455. std::memset(data, 0, count*sizeof(T));
  456. }
  457. else
  458. {
  459. for (std::size_t i=0; i<count; ++i)
  460. data[i] *= multiplier;
  461. }
  462. }
  463. /*
  464. * Clear a byte array.
  465. */
  466. static inline
  467. void carla_zeroBytes(uint8_t bytes[], const std::size_t count) noexcept
  468. {
  469. CARLA_SAFE_ASSERT_RETURN(bytes != nullptr,);
  470. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  471. std::memset(bytes, 0, count*sizeof(uint8_t));
  472. }
  473. /*
  474. * Clear a char array.
  475. */
  476. static inline
  477. void carla_zeroChars(char chars[], const std::size_t count) noexcept
  478. {
  479. CARLA_SAFE_ASSERT_RETURN(chars != nullptr,);
  480. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  481. std::memset(chars, 0, count*sizeof(char));
  482. }
  483. /*
  484. * Clear a pointer array.
  485. */
  486. template<typename T>
  487. static inline
  488. void carla_zeroPointers(T* ptrs[], const std::size_t count) noexcept
  489. {
  490. CARLA_SAFE_ASSERT_RETURN(ptrs != nullptr,);
  491. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  492. std::memset(ptrs, 0, count*sizeof(T*));
  493. }
  494. /*
  495. * Clear a single struct.
  496. */
  497. template <typename T>
  498. static inline
  499. void carla_zeroStruct(T& s) noexcept
  500. {
  501. std::memset(&s, 0, sizeof(T));
  502. }
  503. /*
  504. * Clear a struct array.
  505. */
  506. template <typename T>
  507. static inline
  508. void carla_zeroStructs(T structs[], const std::size_t count) noexcept
  509. {
  510. CARLA_SAFE_ASSERT_RETURN(structs != nullptr,);
  511. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  512. std::memset(structs, 0, count*sizeof(T));
  513. }
  514. /*
  515. * Copy a single struct.
  516. */
  517. template <typename T>
  518. static inline
  519. void carla_copyStruct(T& dest, const T& src) noexcept
  520. {
  521. std::memcpy(&dest, &src, sizeof(T));
  522. }
  523. /*
  524. * Copy a struct array.
  525. */
  526. template <typename T>
  527. static inline
  528. void carla_copyStructs(T dest[], const T src[], const std::size_t count) noexcept
  529. {
  530. CARLA_SAFE_ASSERT_RETURN(dest != nullptr,);
  531. CARLA_SAFE_ASSERT_RETURN(src != nullptr,);
  532. CARLA_SAFE_ASSERT_RETURN(dest != src,);
  533. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  534. std::memcpy(dest, src, count*sizeof(T));
  535. }
  536. // --------------------------------------------------------------------------------------------------------------------
  537. #endif // CARLA_UTILS_HPP_INCLUDED