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.

345 lines
8.5KB

  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.h"
  20. #include "carla_bridge_toolkit.h"
  21. #ifdef BUILD_BRIDGE_PLUGIN
  22. # include "carla_engine.h"
  23. #else
  24. # include "carla_lib_includes.h"
  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. #endif
  53. }
  54. virtual ~CarlaClient()
  55. {
  56. #ifdef BUILD_BRIDGE_UI
  57. if (m_filename)
  58. free(m_filename);
  59. #endif
  60. }
  61. // ---------------------------------------------------------------------
  62. void quequeMessage(const MessageType type, const int32_t value1, const int32_t value2, const double value3)
  63. {
  64. const QMutexLocker locker(&m_messages.lock);
  65. for (unsigned int i=0; i < MAX_BRIDGE_MESSAGES; i++)
  66. {
  67. Message* const m = &m_messages.data[i];
  68. if (m->type == MESSAGE_NULL)
  69. {
  70. m->type = type;
  71. m->value1 = value1;
  72. m->value2 = value2;
  73. m->value3 = value3;
  74. break;
  75. }
  76. }
  77. }
  78. bool runMessages()
  79. {
  80. const QMutexLocker locker(&m_messages.lock);
  81. for (unsigned int i=0; i < MAX_BRIDGE_MESSAGES; i++)
  82. {
  83. Message* const m = &m_messages.data[i];
  84. switch (m->type)
  85. {
  86. case MESSAGE_NULL:
  87. return true;
  88. case MESSAGE_PARAMETER:
  89. setParameter(m->value1, m->value3);
  90. break;
  91. case MESSAGE_PROGRAM:
  92. setProgram(m->value1);
  93. break;
  94. case MESSAGE_MIDI_PROGRAM:
  95. #ifdef BUILD_BRIDGE_PLUGIN
  96. setMidiProgram(m->value1);
  97. #else
  98. setMidiProgram(m->value1, m->value2);
  99. #endif
  100. break;
  101. case MESSAGE_NOTE_ON:
  102. noteOn(m->value1, m->value2, rint(m->value3));
  103. break;
  104. case MESSAGE_NOTE_OFF:
  105. noteOff(m->value1, m->value2);
  106. break;
  107. case MESSAGE_SHOW_GUI:
  108. if (m->value1)
  109. m_toolkit->show();
  110. else
  111. m_toolkit->hide();
  112. break;
  113. case MESSAGE_RESIZE_GUI:
  114. m_toolkit->resize(m->value1, m->value2);
  115. break;
  116. case MESSAGE_SAVE_NOW:
  117. #ifdef BUILD_BRIDGE_PLUGIN
  118. saveNow();
  119. #endif
  120. break;
  121. case MESSAGE_QUIT:
  122. m_toolkit->quit();
  123. return false;
  124. }
  125. m->type = MESSAGE_NULL;
  126. }
  127. return true;
  128. }
  129. // ---------------------------------------------------------------------
  130. #ifdef BUILD_BRIDGE_UI
  131. // ui initialization
  132. virtual bool init(const char* const, const char* const) = 0;
  133. virtual void close() = 0;
  134. // ui management
  135. virtual void* getWidget() const = 0;
  136. virtual bool isResizable() const = 0;
  137. virtual bool needsReparent() const = 0;
  138. #endif
  139. // processing
  140. virtual void setParameter(const int32_t rindex, const double value) = 0;
  141. virtual void setProgram(const uint32_t index) = 0;
  142. #ifdef BUILD_BRIDGE_PLUGIN
  143. virtual void setMidiProgram(const uint32_t index) = 0;
  144. #endif
  145. #ifdef BUILD_BRIDGE_UI
  146. virtual void setMidiProgram(const uint32_t bank, const uint32_t program) = 0;
  147. #endif
  148. virtual void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) = 0;
  149. virtual void noteOff(const uint8_t channel, const uint8_t note) = 0;
  150. #ifdef BUILD_BRIDGE_PLUGIN
  151. // plugin
  152. virtual void saveNow() = 0;
  153. virtual void setCustomData(const char* const type, const char* const key, const char* const value) = 0;
  154. virtual void setChunkData(const char* const filePath) = 0;
  155. #endif
  156. // ---------------------------------------------------------------------
  157. bool oscInit(const char* const url)
  158. {
  159. qDebug("CarlaClient::oscInit(\"%s\")", url);
  160. return m_osc.init(url);
  161. }
  162. void oscClose()
  163. {
  164. qDebug("CarlaClient::oscClose()");
  165. m_osc.close();
  166. }
  167. #ifdef BUILD_BRIDGE_PLUGIN
  168. void registerOscEngine(CarlaBackend::CarlaEngine* const engine)
  169. {
  170. qDebug("CarlaClient::registerOscEngine(%p)", engine);
  171. engine->setOscBridgeData(m_osc.getControllerData());
  172. }
  173. #endif
  174. void sendOscConfigure(const char* const key, const char* const value)
  175. {
  176. qDebug("CarlaClient::sendOscConfigure(\"%s\", \"%s\")", key, value);
  177. m_osc.sendOscConfigure(key, value);
  178. }
  179. void sendOscControl(const int32_t index, const float value)
  180. {
  181. qDebug("CarlaClient::sendOscControl(%i, %f)", index, value);
  182. m_osc.sendOscControl(index, value);
  183. }
  184. void sendOscProgram(const int32_t index)
  185. {
  186. qDebug("CarlaClient::sendOscProgram(%i)", index);
  187. m_osc.sendOscProgram(index);
  188. }
  189. void sendOscMidiProgram(const int32_t index)
  190. {
  191. qDebug("CarlaClient::sendOscMidiProgram(%i)", index);
  192. m_osc.sendOscMidiProgram(index);
  193. }
  194. void sendOscMidi(const uint8_t midiBuf[4])
  195. {
  196. qDebug("CarlaClient::sendOscMidi(%p)", midiBuf);
  197. m_osc.sendOscMidi(midiBuf);
  198. }
  199. void sendOscUpdate()
  200. {
  201. qDebug("CarlaClient::sendOscUpdate()");
  202. m_osc.sendOscUpdate();
  203. }
  204. void sendOscExiting()
  205. {
  206. qDebug("CarlaClient::sendOscExiting()");
  207. m_osc.sendOscExiting();
  208. }
  209. #ifdef BUILD_BRIDGE_PLUGIN
  210. void sendOscBridgeUpdate()
  211. {
  212. qDebug("CarlaClient::sendOscBridgeUpdate()");
  213. m_osc.sendOscBridgeUpdate();
  214. }
  215. void sendOscBridgeError(const char* const error)
  216. {
  217. qDebug("CarlaClient::sendOscBridgeError(\"%s\")", error);
  218. m_osc.sendOscBridgeError(error);
  219. }
  220. #endif
  221. #ifdef BRIDGE_LV2
  222. void sendOscLv2TransferAtom(const int32_t portIndex, const char* const typeStr, const char* const atomBuf)
  223. {
  224. qDebug("CarlaClient::sendOscLv2TransferAtom(%i, \"%s\", \"%s\")", portIndex, typeStr, atomBuf);
  225. m_osc.sendOscLv2TransferAtom(portIndex, typeStr, atomBuf);
  226. }
  227. void sendOscLv2TransferEvent(const int32_t portIndex, const char* const typeStr, const char* const atomBuf)
  228. {
  229. qDebug("CarlaClient::sendOscLv2TransferEvent(%i, \"%s\", \"%s\")", portIndex, typeStr, atomBuf);
  230. m_osc.sendOscLv2TransferEvent(portIndex, typeStr, atomBuf);
  231. }
  232. #endif
  233. // ---------------------------------------------------------------------
  234. #ifdef BUILD_BRIDGE_UI
  235. protected:
  236. bool libOpen(const char* const filename)
  237. {
  238. Q_ASSERT(filename);
  239. if (m_filename)
  240. free(m_filename);
  241. m_lib = lib_open(filename);
  242. m_filename = strdup(filename ? filename : "");
  243. return bool(m_lib);
  244. }
  245. bool libClose()
  246. {
  247. if (m_lib)
  248. {
  249. const bool closed = lib_close(m_lib);
  250. m_lib = nullptr;
  251. return closed;
  252. }
  253. return false;
  254. }
  255. void* libSymbol(const char* const symbol)
  256. {
  257. if (m_lib)
  258. return lib_symbol(m_lib, symbol);
  259. return nullptr;
  260. }
  261. const char* libError()
  262. {
  263. return lib_error(m_filename);
  264. }
  265. #endif
  266. // ---------------------------------------------------------------------
  267. private:
  268. CarlaBridgeOsc m_osc;
  269. CarlaToolkit* const m_toolkit;
  270. struct {
  271. Message data[MAX_BRIDGE_MESSAGES];
  272. QMutex lock;
  273. } m_messages;
  274. #ifdef BUILD_BRIDGE_UI
  275. char* m_filename;
  276. void* m_lib;
  277. #endif
  278. };
  279. /**@}*/
  280. CARLA_BRIDGE_END_NAMESPACE
  281. #endif // CARLA_BRIDGE_CLIENT_H