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.

427 lines
10KB

  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. class CarlaClient
  39. {
  40. public:
  41. CarlaClient(CarlaToolkit* const toolkit)
  42. #ifdef BUILD_BRIDGE_PLUGIN
  43. : m_osc(this, "carla-bridge-plugin"),
  44. #else
  45. : m_osc(this, "carla-bridge-ui"),
  46. #endif
  47. m_toolkit(toolkit)
  48. {
  49. #ifdef BUILD_BRIDGE_UI
  50. m_filename = nullptr;
  51. m_lib = nullptr;
  52. m_quit = false;
  53. #endif
  54. m_toolkit->m_client = this;
  55. }
  56. virtual ~CarlaClient()
  57. {
  58. #ifdef BUILD_BRIDGE_UI
  59. if (m_filename)
  60. free(m_filename);
  61. #endif
  62. }
  63. // ---------------------------------------------------------------------
  64. #if 0
  65. void quequeMessage(const MessageType type, const int32_t value1, const int32_t value2, const double value3)
  66. {
  67. const QMutexLocker locker(&m_messages.lock);
  68. for (unsigned int i=0; i < MAX_BRIDGE_MESSAGES; i++)
  69. {
  70. Message* const m = &m_messages.data[i];
  71. if (m->type == MESSAGE_NULL)
  72. {
  73. m->type = type;
  74. m->value1 = value1;
  75. m->value2 = value2;
  76. m->value3 = value3;
  77. break;
  78. }
  79. }
  80. }
  81. bool runMessages()
  82. {
  83. const QMutexLocker locker(&m_messages.lock);
  84. for (unsigned int i=0; i < MAX_BRIDGE_MESSAGES; i++)
  85. {
  86. Message* const m = &m_messages.data[i];
  87. switch (m->type)
  88. {
  89. case MESSAGE_NULL:
  90. return true;
  91. case MESSAGE_PARAMETER:
  92. setParameter(m->value1, m->value3);
  93. break;
  94. case MESSAGE_PROGRAM:
  95. setProgram(m->value1);
  96. break;
  97. case MESSAGE_MIDI_PROGRAM:
  98. #ifdef BUILD_BRIDGE_PLUGIN
  99. setMidiProgram(m->value1);
  100. #else
  101. setMidiProgram(m->value1, m->value2);
  102. #endif
  103. break;
  104. case MESSAGE_NOTE_ON:
  105. noteOn(m->value1, m->value2, rint(m->value3));
  106. break;
  107. case MESSAGE_NOTE_OFF:
  108. noteOff(m->value1, m->value2);
  109. break;
  110. case MESSAGE_SHOW_GUI:
  111. if (m->value1)
  112. m_toolkit->show();
  113. else
  114. m_toolkit->hide();
  115. break;
  116. case MESSAGE_RESIZE_GUI:
  117. m_toolkit->resize(m->value1, m->value2);
  118. break;
  119. case MESSAGE_SAVE_NOW:
  120. #ifdef BUILD_BRIDGE_PLUGIN
  121. saveNow();
  122. #endif
  123. break;
  124. case MESSAGE_QUIT:
  125. m_toolkit->quit();
  126. return false;
  127. }
  128. m->type = MESSAGE_NULL;
  129. }
  130. return true;
  131. }
  132. #endif
  133. // ---------------------------------------------------------------------
  134. #ifdef BUILD_BRIDGE_UI
  135. // ui initialization
  136. virtual bool init(const char* const, const char* const)
  137. {
  138. m_quit = false;
  139. return false;
  140. }
  141. virtual void close()
  142. {
  143. if (! m_quit)
  144. {
  145. m_quit = true;
  146. sendOscExiting();
  147. }
  148. }
  149. // ui management
  150. virtual void* getWidget() const = 0;
  151. virtual bool isResizable() const = 0;
  152. virtual bool needsReparent() const = 0;
  153. #endif
  154. // processing
  155. virtual void setParameter(const int32_t rindex, const double value) = 0;
  156. virtual void setProgram(const uint32_t index) = 0;
  157. #ifdef BUILD_BRIDGE_PLUGIN
  158. virtual void setMidiProgram(const uint32_t index) = 0;
  159. #endif
  160. #ifdef BUILD_BRIDGE_UI
  161. virtual void setMidiProgram(const uint32_t bank, const uint32_t program) = 0;
  162. #endif
  163. virtual void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) = 0;
  164. virtual void noteOff(const uint8_t channel, const uint8_t note) = 0;
  165. #ifdef BUILD_BRIDGE_PLUGIN
  166. // plugin
  167. virtual void saveNow() = 0;
  168. virtual void setCustomData(const char* const type, const char* const key, const char* const value) = 0;
  169. virtual void setChunkData(const char* const filePath) = 0;
  170. #endif
  171. // ---------------------------------------------------------------------
  172. bool oscInit(const char* const url)
  173. {
  174. qDebug("CarlaClient::oscInit(\"%s\")", url);
  175. return m_osc.init(url);
  176. }
  177. bool oscIdle()
  178. {
  179. if (m_osc.m_server)
  180. while (lo_server_recv_noblock(m_osc.m_server, 0) != 0) {}
  181. #ifdef BUILD_BRIDGE_UI
  182. return ! m_quit;
  183. #else
  184. return true;
  185. #endif
  186. }
  187. void oscClose()
  188. {
  189. qDebug("CarlaClient::oscClose()");
  190. m_osc.close();
  191. }
  192. void sendOscUpdate()
  193. {
  194. qDebug("CarlaClient::sendOscUpdate()");
  195. CARLA_ASSERT(m_osc.m_controlData.target);
  196. if (m_osc.m_controlData.target)
  197. osc_send_update(&m_osc.m_controlData, m_osc.m_serverPath);
  198. }
  199. #ifdef BUILD_BRIDGE_PLUGIN
  200. void sendOscBridgeError(const char* const error)
  201. {
  202. qDebug("CarlaClient::sendOscBridgeError(\"%s\")", error);
  203. CARLA_ASSERT(m_osc.m_controlData.target);
  204. CARLA_ASSERT(error);
  205. if (m_osc.m_controlData.target)
  206. osc_send_bridge_error(&m_osc.m_controlData, error);
  207. }
  208. void registerOscEngine(CarlaBackend::CarlaEngine* const engine)
  209. {
  210. qDebug("CarlaClient::registerOscEngine(%p)", engine);
  211. engine->setOscBridgeData(&m_osc.m_controlData);
  212. }
  213. #endif
  214. // ---------------------------------------------------------------------
  215. void toolkitShow()
  216. {
  217. m_toolkit->show();
  218. }
  219. void toolkitHide()
  220. {
  221. m_toolkit->hide();
  222. }
  223. void toolkitResize(int width, int height)
  224. {
  225. m_toolkit->resize(width, height);
  226. }
  227. void toolkitQuit()
  228. {
  229. #ifdef BUILD_BRIDGE_UI
  230. m_quit = true;
  231. #endif
  232. m_toolkit->quit();
  233. }
  234. // ---------------------------------------------------------------------
  235. protected:
  236. void sendOscConfigure(const char* const key, const char* const value)
  237. {
  238. qDebug("CarlaClient::sendOscConfigure(\"%s\", \"%s\")", key, value);
  239. if (m_osc.m_controlData.target)
  240. osc_send_configure(&m_osc.m_controlData, key, value);
  241. }
  242. void sendOscControl(const int32_t index, const float value)
  243. {
  244. qDebug("CarlaClient::sendOscControl(%i, %f)", index, value);
  245. if (m_osc.m_controlData.target)
  246. osc_send_control(&m_osc.m_controlData, index, value);
  247. }
  248. void sendOscProgram(const int32_t index)
  249. {
  250. qDebug("CarlaClient::sendOscProgram(%i)", index);
  251. if (m_osc.m_controlData.target)
  252. osc_send_program(&m_osc.m_controlData, index);
  253. }
  254. void sendOscMidiProgram(const int32_t index)
  255. {
  256. qDebug("CarlaClient::sendOscMidiProgram(%i)", index);
  257. if (m_osc.m_controlData.target)
  258. osc_send_midi_program(&m_osc.m_controlData, index);
  259. }
  260. void sendOscMidi(const uint8_t midiBuf[4])
  261. {
  262. qDebug("CarlaClient::sendOscMidi(%p)", midiBuf);
  263. if (m_osc.m_controlData.target)
  264. osc_send_midi(&m_osc.m_controlData, midiBuf);
  265. }
  266. void sendOscExiting()
  267. {
  268. qDebug("CarlaClient::sendOscExiting()");
  269. if (m_osc.m_controlData.target)
  270. osc_send_exiting(&m_osc.m_controlData);
  271. }
  272. #ifdef BUILD_BRIDGE_PLUGIN
  273. void sendOscBridgeUpdate()
  274. {
  275. qDebug("CarlaClient::sendOscBridgeUpdate()");
  276. CARLA_ASSERT(m_osc.m_controlData.target && m_osc.m_serverPath);
  277. if (m_osc.m_controlData.target && m_osc.m_serverPath)
  278. osc_send_bridge_update(&m_osc.m_controlData, m_osc.m_serverPath);
  279. }
  280. #endif
  281. #ifdef BRIDGE_LV2
  282. void sendOscLv2TransferAtom(const int32_t portIndex, const char* const typeStr, const char* const atomBuf)
  283. {
  284. qDebug("CarlaClient::sendOscLv2TransferAtom(%i, \"%s\", \"%s\")", portIndex, typeStr, atomBuf);
  285. if (m_osc.m_controlData.target)
  286. osc_send_lv2_transfer_atom(&m_osc.m_controlData, portIndex, typeStr, atomBuf);
  287. }
  288. void sendOscLv2TransferEvent(const int32_t portIndex, const char* const typeStr, const char* const atomBuf)
  289. {
  290. qDebug("CarlaClient::sendOscLv2TransferEvent(%i, \"%s\", \"%s\")", portIndex, typeStr, atomBuf);
  291. if (m_osc.m_controlData.target)
  292. osc_send_lv2_transfer_event(&m_osc.m_controlData, portIndex, typeStr, atomBuf);
  293. }
  294. #endif
  295. // ---------------------------------------------------------------------
  296. #ifdef BUILD_BRIDGE_UI
  297. void* getContainerId()
  298. {
  299. return m_toolkit->getContainerId();
  300. }
  301. bool libOpen(const char* const filename)
  302. {
  303. CARLA_ASSERT(filename);
  304. if (m_filename)
  305. free(m_filename);
  306. m_lib = lib_open(filename);
  307. m_filename = strdup(filename ? filename : "");
  308. return bool(m_lib);
  309. }
  310. bool libClose()
  311. {
  312. if (m_lib)
  313. {
  314. const bool closed = lib_close(m_lib);
  315. m_lib = nullptr;
  316. return closed;
  317. }
  318. return false;
  319. }
  320. void* libSymbol(const char* const symbol)
  321. {
  322. if (m_lib)
  323. return lib_symbol(m_lib, symbol);
  324. return nullptr;
  325. }
  326. const char* libError()
  327. {
  328. return lib_error(m_filename);
  329. }
  330. #endif
  331. // ---------------------------------------------------------------------
  332. private:
  333. CarlaBridgeOsc m_osc;
  334. CarlaToolkit* const m_toolkit;
  335. #ifdef BUILD_BRIDGE_UI
  336. char* m_filename;
  337. void* m_lib;
  338. bool m_quit;
  339. #endif
  340. };
  341. /**@}*/
  342. CARLA_BRIDGE_END_NAMESPACE
  343. #endif // CARLA_BRIDGE_CLIENT_H