Collection of tools useful for audio production
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.

349 lines
8.6KB

  1. /*
  2. * Carla bridge code
  3. * Copyright (C) 2011-2012 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_BRIDGE_CLIENT_H
  18. #define CARLA_BRIDGE_CLIENT_H
  19. #include "carla_bridge_osc.hpp"
  20. #include "carla_bridge_toolkit.hpp"
  21. #ifdef BUILD_BRIDGE_PLUGIN
  22. # include "carla_engine.hpp"
  23. #else
  24. # include "carla_lib_utils.hpp"
  25. #endif
  26. #include <cmath>
  27. #include <cstdio>
  28. #include <cstdint>
  29. #include <cstdlib>
  30. #include <QtCore/QMutex>
  31. CARLA_BRIDGE_START_NAMESPACE
  32. /*!
  33. * @defgroup CarlaBridgeClient Carla Bridge Client
  34. *
  35. * The Carla Bridge Client.
  36. * @{
  37. */
  38. #ifdef BUILD_BRIDGE_PLUGIN
  39. const char* const carlaClientName = "carla-bridge-plugin";
  40. #else
  41. const char* const carlaClientName = "carla-bridge-ui";
  42. #endif
  43. class CarlaClient
  44. {
  45. public:
  46. CarlaClient(CarlaToolkit* const toolkit)
  47. : m_osc(this, carlaClientName),
  48. m_toolkit(toolkit)
  49. {
  50. #ifdef BUILD_BRIDGE_UI
  51. m_filename = nullptr;
  52. m_lib = nullptr;
  53. m_quit = false;
  54. #endif
  55. m_toolkit->m_client = this;
  56. }
  57. virtual ~CarlaClient()
  58. {
  59. #ifdef BUILD_BRIDGE_UI
  60. if (m_filename)
  61. free(m_filename);
  62. #endif
  63. }
  64. // ---------------------------------------------------------------------
  65. // ui initialization
  66. #ifdef BUILD_BRIDGE_UI
  67. virtual bool init(const char* const, const char* const)
  68. {
  69. m_quit = false;
  70. return false;
  71. }
  72. virtual void close()
  73. {
  74. if (! m_quit)
  75. {
  76. m_quit = true;
  77. sendOscExiting();
  78. }
  79. }
  80. #endif
  81. // ---------------------------------------------------------------------
  82. // ui management
  83. #ifdef BUILD_BRIDGE_UI
  84. virtual void* getWidget() const = 0;
  85. virtual bool isResizable() const = 0;
  86. virtual bool needsReparent() const = 0;
  87. #endif
  88. // ---------------------------------------------------------------------
  89. // processing
  90. virtual void setParameter(const int32_t rindex, const double value) = 0;
  91. virtual void setProgram(const uint32_t index) = 0;
  92. #ifdef BUILD_BRIDGE_PLUGIN
  93. virtual void setMidiProgram(const uint32_t index) = 0;
  94. #endif
  95. #ifdef BUILD_BRIDGE_UI
  96. virtual void setMidiProgram(const uint32_t bank, const uint32_t program) = 0;
  97. #endif
  98. virtual void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) = 0;
  99. virtual void noteOff(const uint8_t channel, const uint8_t note) = 0;
  100. // ---------------------------------------------------------------------
  101. // plugin
  102. #ifdef BUILD_BRIDGE_PLUGIN
  103. virtual void saveNow() = 0;
  104. virtual void setCustomData(const char* const type, const char* const key, const char* const value) = 0;
  105. virtual void setChunkData(const char* const filePath) = 0;
  106. #endif
  107. // ---------------------------------------------------------------------
  108. bool oscInit(const char* const url)
  109. {
  110. qDebug("CarlaClient::oscInit(\"%s\")", url);
  111. return m_osc.init(url);
  112. }
  113. bool oscIdle()
  114. {
  115. if (m_osc.m_server)
  116. while (lo_server_recv_noblock(m_osc.m_server, 0) != 0) {}
  117. #ifdef BUILD_BRIDGE_UI
  118. return ! m_quit;
  119. #else
  120. return true;
  121. #endif
  122. }
  123. void oscClose()
  124. {
  125. qDebug("CarlaClient::oscClose()");
  126. m_osc.close();
  127. }
  128. void sendOscUpdate()
  129. {
  130. qDebug("CarlaClient::sendOscUpdate()");
  131. CARLA_ASSERT(m_osc.m_controlData.target);
  132. if (m_osc.m_controlData.target)
  133. osc_send_update(&m_osc.m_controlData, m_osc.m_serverPath);
  134. }
  135. #ifdef BUILD_BRIDGE_PLUGIN
  136. void sendOscBridgeError(const char* const error)
  137. {
  138. qDebug("CarlaClient::sendOscBridgeError(\"%s\")", error);
  139. CARLA_ASSERT(m_osc.m_controlData.target);
  140. CARLA_ASSERT(error);
  141. if (m_osc.m_controlData.target)
  142. osc_send_bridge_error(&m_osc.m_controlData, error);
  143. }
  144. void registerOscEngine(CarlaBackend::CarlaEngine* const engine)
  145. {
  146. qDebug("CarlaClient::registerOscEngine(%p)", engine);
  147. engine->setOscBridgeData(&m_osc.m_controlData);
  148. }
  149. #endif
  150. // ---------------------------------------------------------------------
  151. void toolkitShow()
  152. {
  153. m_toolkit->show();
  154. }
  155. void toolkitHide()
  156. {
  157. m_toolkit->hide();
  158. }
  159. void toolkitResize(int width, int height)
  160. {
  161. m_toolkit->resize(width, height);
  162. }
  163. void toolkitQuit()
  164. {
  165. #ifdef BUILD_BRIDGE_UI
  166. m_quit = true;
  167. #endif
  168. m_toolkit->quit();
  169. }
  170. // ---------------------------------------------------------------------
  171. protected:
  172. void sendOscConfigure(const char* const key, const char* const value)
  173. {
  174. qDebug("CarlaClient::sendOscConfigure(\"%s\", \"%s\")", key, value);
  175. if (m_osc.m_controlData.target)
  176. osc_send_configure(&m_osc.m_controlData, key, value);
  177. }
  178. void sendOscControl(const int32_t index, const float value)
  179. {
  180. qDebug("CarlaClient::sendOscControl(%i, %f)", index, value);
  181. if (m_osc.m_controlData.target)
  182. osc_send_control(&m_osc.m_controlData, index, value);
  183. }
  184. void sendOscProgram(const int32_t index)
  185. {
  186. qDebug("CarlaClient::sendOscProgram(%i)", index);
  187. if (m_osc.m_controlData.target)
  188. osc_send_program(&m_osc.m_controlData, index);
  189. }
  190. void sendOscMidiProgram(const int32_t index)
  191. {
  192. qDebug("CarlaClient::sendOscMidiProgram(%i)", index);
  193. if (m_osc.m_controlData.target)
  194. osc_send_midi_program(&m_osc.m_controlData, index);
  195. }
  196. void sendOscMidi(const uint8_t midiBuf[4])
  197. {
  198. qDebug("CarlaClient::sendOscMidi(%p)", midiBuf);
  199. if (m_osc.m_controlData.target)
  200. osc_send_midi(&m_osc.m_controlData, midiBuf);
  201. }
  202. void sendOscExiting()
  203. {
  204. qDebug("CarlaClient::sendOscExiting()");
  205. if (m_osc.m_controlData.target)
  206. osc_send_exiting(&m_osc.m_controlData);
  207. }
  208. #ifdef BUILD_BRIDGE_PLUGIN
  209. void sendOscBridgeUpdate()
  210. {
  211. qDebug("CarlaClient::sendOscBridgeUpdate()");
  212. CARLA_ASSERT(m_osc.m_controlData.target && m_osc.m_serverPath);
  213. if (m_osc.m_controlData.target && m_osc.m_serverPath)
  214. osc_send_bridge_update(&m_osc.m_controlData, m_osc.m_serverPath);
  215. }
  216. #endif
  217. #ifdef BRIDGE_LV2
  218. void sendOscLv2TransferAtom(const int32_t portIndex, const char* const typeStr, const char* const atomBuf)
  219. {
  220. qDebug("CarlaClient::sendOscLv2TransferAtom(%i, \"%s\", \"%s\")", portIndex, typeStr, atomBuf);
  221. if (m_osc.m_controlData.target)
  222. osc_send_lv2_transfer_atom(&m_osc.m_controlData, portIndex, typeStr, atomBuf);
  223. }
  224. void sendOscLv2TransferEvent(const int32_t portIndex, const char* const typeStr, const char* const atomBuf)
  225. {
  226. qDebug("CarlaClient::sendOscLv2TransferEvent(%i, \"%s\", \"%s\")", portIndex, typeStr, atomBuf);
  227. if (m_osc.m_controlData.target)
  228. osc_send_lv2_transfer_event(&m_osc.m_controlData, portIndex, typeStr, atomBuf);
  229. }
  230. #endif
  231. // ---------------------------------------------------------------------
  232. #ifdef BUILD_BRIDGE_UI
  233. void* getContainerId()
  234. {
  235. return m_toolkit->getContainerId();
  236. }
  237. bool libOpen(const char* const filename)
  238. {
  239. CARLA_ASSERT(filename);
  240. if (m_filename)
  241. free(m_filename);
  242. m_lib = lib_open(filename);
  243. m_filename = strdup(filename ? filename : "");
  244. return bool(m_lib);
  245. }
  246. bool libClose()
  247. {
  248. if (m_lib)
  249. {
  250. const bool closed = lib_close(m_lib);
  251. m_lib = nullptr;
  252. return closed;
  253. }
  254. return false;
  255. }
  256. void* libSymbol(const char* const symbol)
  257. {
  258. if (m_lib)
  259. return lib_symbol(m_lib, symbol);
  260. return nullptr;
  261. }
  262. const char* libError()
  263. {
  264. return lib_error(m_filename);
  265. }
  266. #endif
  267. // ---------------------------------------------------------------------
  268. private:
  269. CarlaBridgeOsc m_osc;
  270. CarlaToolkit* const m_toolkit;
  271. #ifdef BUILD_BRIDGE_UI
  272. char* m_filename;
  273. void* m_lib;
  274. bool m_quit;
  275. #endif
  276. };
  277. /**@}*/
  278. CARLA_BRIDGE_END_NAMESPACE
  279. #endif // CARLA_BRIDGE_CLIENT_H