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.

338 lines
8.2KB

  1. /*
  2. * Carla bridge code
  3. * Copyright (C) 2011-2012 Filipe Coelho <falktx@gmail.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. #else
  145. virtual void setMidiProgram(const uint32_t bank, const uint32_t program) = 0;
  146. #endif
  147. virtual void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) = 0;
  148. virtual void noteOff(const uint8_t channel, const uint8_t note) = 0;
  149. #ifdef BUILD_BRIDGE_PLUGIN
  150. // plugin
  151. virtual void saveNow() = 0;
  152. virtual void setCustomData(const char* const type, const char* const key, const char* const value) = 0;
  153. virtual void setChunkData(const char* const filePath) = 0;
  154. #endif
  155. // ---------------------------------------------------------------------
  156. bool oscInit(const char* const url)
  157. {
  158. qDebug("CarlaClient::oscInit(\"%s\")", url);
  159. return m_osc.init(url);
  160. }
  161. void oscClose()
  162. {
  163. qDebug("CarlaClient::oscClose()");
  164. m_osc.close();
  165. }
  166. #ifdef BUILD_BRIDGE_PLUGIN
  167. void registerOscEngine(CarlaBackend::CarlaEngine* const engine)
  168. {
  169. qDebug("CarlaClient::registerOscEngine(%p)", engine);
  170. engine->setOscBridgeData(m_osc.getControllerData());
  171. }
  172. #endif
  173. void sendOscConfigure(const char* const key, const char* const value)
  174. {
  175. qDebug("CarlaClient::sendOscConfigure(\"%s\", \"%s\")", key, value);
  176. m_osc.sendOscConfigure(key, value);
  177. }
  178. void sendOscControl(const int32_t index, const float value)
  179. {
  180. qDebug("CarlaClient::sendOscControl(%i, %f)", index, value);
  181. m_osc.sendOscControl(index, value);
  182. }
  183. void sendOscProgram(const int32_t index)
  184. {
  185. qDebug("CarlaClient::sendOscProgram(%i)", index);
  186. m_osc.sendOscProgram(index);
  187. }
  188. void sendOscMidiProgram(const int32_t index)
  189. {
  190. qDebug("CarlaClient::sendOscMidiProgram(%i)", index);
  191. m_osc.sendOscMidiProgram(index);
  192. }
  193. void sendOscMidi(const uint8_t midiBuf[4])
  194. {
  195. qDebug("CarlaClient::sendOscMidi(%p)", midiBuf);
  196. m_osc.sendOscMidi(midiBuf);
  197. }
  198. void sendOscUpdate()
  199. {
  200. qDebug("CarlaClient::sendOscUpdate()");
  201. m_osc.sendOscUpdate();
  202. }
  203. void sendOscExiting()
  204. {
  205. qDebug("CarlaClient::sendOscExiting()");
  206. m_osc.sendOscExiting();
  207. }
  208. #ifdef BUILD_BRIDGE_PLUGIN
  209. void sendOscBridgeUpdate()
  210. {
  211. qDebug("CarlaClient::sendOscBridgeUpdate()");
  212. m_osc.sendOscBridgeUpdate();
  213. }
  214. #endif
  215. #ifdef BRIDGE_LV2
  216. void sendOscLv2TransferAtom(const char* const type, const char* const value)
  217. {
  218. qDebug("CarlaClient::sendOscLv2TransferAtom(\"%s\", \"%s\")", type, value);
  219. m_osc.sendOscLv2TransferAtom(type, value);
  220. }
  221. void sendOscLv2TransferEvent(const char* const type, const char* const value)
  222. {
  223. qDebug("CarlaClient::sendOscLv2TransferEvent(\"%s\", \"%s\")", type, value);
  224. m_osc.sendOscLv2TransferEvent(type, value);
  225. }
  226. #endif
  227. // ---------------------------------------------------------------------
  228. #ifdef BUILD_BRIDGE_UI
  229. protected:
  230. bool libOpen(const char* const filename)
  231. {
  232. Q_ASSERT(filename);
  233. if (m_filename)
  234. free(m_filename);
  235. m_lib = lib_open(filename);
  236. m_filename = strdup(filename ? filename : "");
  237. return bool(m_lib);
  238. }
  239. bool libClose()
  240. {
  241. if (m_lib)
  242. {
  243. const bool closed = lib_close(m_lib);
  244. m_lib = nullptr;
  245. return closed;
  246. }
  247. return false;
  248. }
  249. void* libSymbol(const char* const symbol)
  250. {
  251. if (m_lib)
  252. return lib_symbol(m_lib, symbol);
  253. return nullptr;
  254. }
  255. const char* libError()
  256. {
  257. return lib_error(m_filename);
  258. }
  259. #endif
  260. // ---------------------------------------------------------------------
  261. private:
  262. CarlaOsc m_osc;
  263. CarlaToolkit* const m_toolkit;
  264. struct {
  265. Message data[MAX_BRIDGE_MESSAGES];
  266. QMutex lock;
  267. } m_messages;
  268. #ifdef BUILD_BRIDGE_UI
  269. char* m_filename;
  270. void* m_lib;
  271. #endif
  272. };
  273. /**@}*/
  274. CARLA_BRIDGE_END_NAMESPACE
  275. #endif // CARLA_BRIDGE_CLIENT_H