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.

291 lines
8.2KB

  1. /*
  2. * Carla Plugin Host
  3. * Copyright (C) 2011-2019 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. #include "CarlaUtils.h"
  18. #include "CarlaPipeUtils.hpp"
  19. #ifdef CARLA_OS_HAIKU
  20. # include "CarlaStringList.hpp"
  21. # define CARLA_PIPE_WITHOUT_CALLBACK
  22. #endif
  23. namespace CB = CarlaBackend;
  24. // -------------------------------------------------------------------------------------------------------------------
  25. class ExposedCarlaPipeClient : public CarlaPipeClient
  26. {
  27. public:
  28. ExposedCarlaPipeClient(const CarlaPipeCallbackFunc callbackFunc, void* const callbackPtr) noexcept
  29. : CarlaPipeClient(),
  30. fCallbackFunc(callbackFunc),
  31. fCallbackPtr(callbackPtr),
  32. #ifdef CARLA_PIPE_WITHOUT_CALLBACK
  33. fMsgsReceived(),
  34. fLastMsgReceived(nullptr),
  35. #endif
  36. fLastReadLine(nullptr)
  37. {
  38. CARLA_SAFE_ASSERT(fCallbackFunc != nullptr);
  39. }
  40. ~ExposedCarlaPipeClient() override
  41. {
  42. if (fLastReadLine != nullptr)
  43. {
  44. delete[] fLastReadLine;
  45. fLastReadLine = nullptr;
  46. }
  47. #ifdef CARLA_PIPE_WITHOUT_CALLBACK
  48. if (fLastMsgReceived != nullptr)
  49. {
  50. delete[] fLastMsgReceived;
  51. fLastMsgReceived = nullptr;
  52. }
  53. #endif
  54. }
  55. const char* idlePipeAndReturnMessage() noexcept
  56. {
  57. CarlaPipeClient::idlePipe();
  58. #ifdef CARLA_PIPE_WITHOUT_CALLBACK
  59. if (fMsgsReceived.count() == 0)
  60. return nullptr;
  61. delete[] fLastMsgReceived;
  62. fLastMsgReceived = fMsgsReceived.getAndRemoveFirst();
  63. return fLastMsgReceived;
  64. #else
  65. return nullptr;
  66. #endif
  67. }
  68. const char* readlineblock(const uint timeout) noexcept
  69. {
  70. #ifdef CARLA_PIPE_WITHOUT_CALLBACK
  71. if (fMsgsReceived.count() != 0)
  72. {
  73. delete[] fLastMsgReceived;
  74. fLastMsgReceived = fMsgsReceived.getAndRemoveFirst();
  75. return fLastMsgReceived;
  76. }
  77. #endif
  78. delete[] fLastReadLine;
  79. fLastReadLine = CarlaPipeClient::_readlineblock(true, 0, timeout);
  80. return fLastReadLine;
  81. }
  82. bool readlineblock_bool(const uint timeout) noexcept
  83. {
  84. #ifdef CARLA_PIPE_WITHOUT_CALLBACK
  85. if (fMsgsReceived.count() != 0)
  86. {
  87. delete[] fLastMsgReceived;
  88. fLastMsgReceived = fMsgsReceived.getAndRemoveFirst();
  89. return fLastMsgReceived != nullptr && std::strcmp(fLastMsgReceived, "true") == 0;
  90. }
  91. #endif
  92. if (const char* const line = CarlaPipeClient::_readlineblock(false, 0, timeout))
  93. return std::strcmp(line, "true") == 0;
  94. return false;
  95. }
  96. int readlineblock_int(const uint timeout) noexcept
  97. {
  98. #ifdef CARLA_PIPE_WITHOUT_CALLBACK
  99. if (fMsgsReceived.count() != 0)
  100. {
  101. delete[] fLastMsgReceived;
  102. fLastMsgReceived = fMsgsReceived.getAndRemoveFirst();
  103. return fLastMsgReceived != nullptr && std::strcmp(fLastMsgReceived, "true") == 0;
  104. }
  105. #endif
  106. if (const char* const line = CarlaPipeClient::_readlineblock(false, 0, timeout))
  107. return std::atoi(line);
  108. return 0;
  109. }
  110. double readlineblock_float(const uint timeout) noexcept
  111. {
  112. #ifdef CARLA_PIPE_WITHOUT_CALLBACK
  113. if (fMsgsReceived.count() != 0)
  114. {
  115. delete[] fLastMsgReceived;
  116. fLastMsgReceived = fMsgsReceived.getAndRemoveFirst();
  117. return fLastMsgReceived != nullptr && std::strcmp(fLastMsgReceived, "true") == 0;
  118. }
  119. #endif
  120. if (const char* const line = CarlaPipeClient::_readlineblock(false, 0, timeout))
  121. return std::atof(line);
  122. return 0.0;
  123. }
  124. bool msgReceived(const char* const msg) noexcept override
  125. {
  126. #ifdef CARLA_PIPE_WITHOUT_CALLBACK
  127. fMsgsReceived.append(msg);
  128. #else
  129. if (fCallbackFunc != nullptr)
  130. {
  131. try {
  132. fCallbackFunc(fCallbackPtr, msg);
  133. } CARLA_SAFE_EXCEPTION("msgReceived");
  134. }
  135. #endif
  136. return true;
  137. }
  138. private:
  139. const CarlaPipeCallbackFunc fCallbackFunc;
  140. void* const fCallbackPtr;
  141. #ifdef CARLA_PIPE_WITHOUT_CALLBACK
  142. CarlaStringList fMsgsReceived;
  143. const char* fLastMsgReceived;
  144. #endif
  145. const char* fLastReadLine;
  146. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExposedCarlaPipeClient)
  147. };
  148. CarlaPipeClientHandle carla_pipe_client_new(const char* argv[], CarlaPipeCallbackFunc callbackFunc, void* callbackPtr)
  149. {
  150. carla_debug("carla_pipe_client_new(%p, %p, %p)", argv, callbackFunc, callbackPtr);
  151. ExposedCarlaPipeClient* const pipe = new ExposedCarlaPipeClient(callbackFunc, callbackPtr);
  152. if (! pipe->initPipeClient(argv))
  153. {
  154. delete pipe;
  155. return nullptr;
  156. }
  157. return pipe;
  158. }
  159. const char* carla_pipe_client_idle(CarlaPipeClientHandle handle)
  160. {
  161. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
  162. return ((ExposedCarlaPipeClient*)handle)->idlePipeAndReturnMessage();
  163. }
  164. bool carla_pipe_client_is_running(CarlaPipeClientHandle handle)
  165. {
  166. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false);
  167. return ((ExposedCarlaPipeClient*)handle)->isPipeRunning();
  168. }
  169. void carla_pipe_client_lock(CarlaPipeClientHandle handle)
  170. {
  171. CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
  172. return ((ExposedCarlaPipeClient*)handle)->lockPipe();
  173. }
  174. void carla_pipe_client_unlock(CarlaPipeClientHandle handle)
  175. {
  176. CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
  177. return ((ExposedCarlaPipeClient*)handle)->unlockPipe();
  178. }
  179. const char* carla_pipe_client_readlineblock(CarlaPipeClientHandle handle, uint timeout)
  180. {
  181. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
  182. return ((ExposedCarlaPipeClient*)handle)->readlineblock(timeout);
  183. }
  184. bool carla_pipe_client_readlineblock_bool(CarlaPipeClientHandle handle, uint timeout)
  185. {
  186. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false);
  187. return ((ExposedCarlaPipeClient*)handle)->readlineblock_bool(timeout);
  188. }
  189. int carla_pipe_client_readlineblock_int(CarlaPipeClientHandle handle, uint timeout)
  190. {
  191. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 0);
  192. return ((ExposedCarlaPipeClient*)handle)->readlineblock_int(timeout);
  193. }
  194. double carla_pipe_client_readlineblock_float(CarlaPipeClientHandle handle, uint timeout)
  195. {
  196. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 0.0);
  197. return ((ExposedCarlaPipeClient*)handle)->readlineblock_float(timeout);
  198. }
  199. bool carla_pipe_client_write_msg(CarlaPipeClientHandle handle, const char* msg)
  200. {
  201. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false);
  202. return ((ExposedCarlaPipeClient*)handle)->writeMessage(msg);
  203. }
  204. bool carla_pipe_client_write_and_fix_msg(CarlaPipeClientHandle handle, const char* msg)
  205. {
  206. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false);
  207. return ((ExposedCarlaPipeClient*)handle)->writeAndFixMessage(msg);
  208. }
  209. bool carla_pipe_client_flush(CarlaPipeClientHandle handle)
  210. {
  211. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false);
  212. return ((ExposedCarlaPipeClient*)handle)->flushMessages();
  213. }
  214. bool carla_pipe_client_flush_and_unlock(CarlaPipeClientHandle handle)
  215. {
  216. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, false);
  217. ExposedCarlaPipeClient* const pipe = (ExposedCarlaPipeClient*)handle;
  218. const bool ret = pipe->flushMessages();
  219. pipe->unlockPipe();
  220. return ret;
  221. }
  222. void carla_pipe_client_destroy(CarlaPipeClientHandle handle)
  223. {
  224. CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
  225. carla_debug("carla_pipe_client_destroy(%p)", handle);
  226. ExposedCarlaPipeClient* const pipe = (ExposedCarlaPipeClient*)handle;
  227. pipe->closePipeClient();
  228. delete pipe;
  229. }
  230. // -------------------------------------------------------------------------------------------------------------------
  231. #include "CarlaPipeUtils.cpp"
  232. // -------------------------------------------------------------------------------------------------------------------