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.

304 lines
7.4KB

  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. setMidiProgram(m->value1, m->value2);
  96. break;
  97. case MESSAGE_NOTE_ON:
  98. noteOn(m->value1, m->value2, rint(m->value3));
  99. break;
  100. case MESSAGE_NOTE_OFF:
  101. noteOff(m->value1, m->value2);
  102. break;
  103. case MESSAGE_SHOW_GUI:
  104. if (m->value1)
  105. m_toolkit->show();
  106. else
  107. m_toolkit->hide();
  108. break;
  109. case MESSAGE_RESIZE_GUI:
  110. m_toolkit->resize(m->value1, m->value2);
  111. break;
  112. case MESSAGE_SAVE_NOW:
  113. #ifdef BUILD_BRIDGE_PLUGIN
  114. saveNow();
  115. #endif
  116. break;
  117. case MESSAGE_QUIT:
  118. m_toolkit->quit();
  119. return false;
  120. }
  121. m->type = MESSAGE_NULL;
  122. }
  123. return true;
  124. }
  125. // ---------------------------------------------------------------------
  126. #ifdef BUILD_BRIDGE_UI
  127. // ui initialization
  128. virtual bool init(const char* const, const char* const) = 0;
  129. virtual void close() = 0;
  130. // ui management
  131. virtual void* getWidget() const = 0;
  132. virtual bool isResizable() const = 0;
  133. virtual bool needsReparent() const = 0;
  134. #endif
  135. // processing
  136. virtual void setParameter(const int32_t rindex, const double value) = 0;
  137. virtual void setProgram(const uint32_t index) = 0;
  138. virtual void setMidiProgram(const uint32_t bank, const uint32_t program) = 0;
  139. virtual void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) = 0;
  140. virtual void noteOff(const uint8_t channel, const uint8_t note) = 0;
  141. #ifdef BUILD_BRIDGE_PLUGIN
  142. // plugin
  143. virtual void saveNow() = 0;
  144. virtual void setCustomData(const char* const type, const char* const key, const char* const value) = 0;
  145. virtual void setChunkData(const char* const filePath) = 0;
  146. #endif
  147. // ---------------------------------------------------------------------
  148. bool oscInit(const char* const url)
  149. {
  150. qDebug("CarlaClient::oscInit(\"%s\")", url);
  151. return m_osc.init(url);
  152. }
  153. void oscClose()
  154. {
  155. qDebug("CarlaClient::oscClose()");
  156. m_osc.close();
  157. }
  158. #ifdef BUILD_BRIDGE_PLUGIN
  159. void registerOscEngine(CarlaBackend::CarlaEngine* const engine)
  160. {
  161. qDebug("CarlaClient::registerOscEngine(%p)", engine);
  162. engine->setOscBridgeData(m_osc.getControllerData());
  163. }
  164. #endif
  165. void sendOscConfigure(const char* const key, const char* const value)
  166. {
  167. qDebug("CarlaClient::sendOscConfigure(\"%s\", \"%s\")", key, value);
  168. m_osc.sendOscConfigure(key, value);
  169. }
  170. void sendOscControl(const int32_t index, const float value)
  171. {
  172. qDebug("CarlaClient::sendOscControl(%i, %f)", index, value);
  173. m_osc.sendOscControl(index, value);
  174. }
  175. void sendOscUpdate()
  176. {
  177. qDebug("CarlaClient::sendOscUpdate()");
  178. m_osc.sendOscUpdate();
  179. }
  180. void sendOscExiting()
  181. {
  182. qDebug("CarlaClient::sendOscExiting()");
  183. m_osc.sendOscExiting();
  184. }
  185. #ifdef BRIDGE_LV2
  186. void sendOscLv2TransferAtom(const char* const type, const char* const value)
  187. {
  188. qDebug("CarlaClient::sendOscLv2TransferAtom(\"%s\", \"%s\")", type, value);
  189. m_osc.sendOscLv2TransferAtom(type, value);
  190. }
  191. void sendOscLv2TransferEvent(const char* const type, const char* const value)
  192. {
  193. qDebug("CarlaClient::sendOscLv2TransferEvent(\"%s\", \"%s\")", type, value);
  194. m_osc.sendOscLv2TransferEvent(type, value);
  195. }
  196. #endif
  197. // ---------------------------------------------------------------------
  198. #ifdef BUILD_BRIDGE_UI
  199. protected:
  200. bool libOpen(const char* const filename)
  201. {
  202. Q_ASSERT(filename);
  203. if (m_filename)
  204. free(m_filename);
  205. m_lib = lib_open(filename);
  206. m_filename = strdup(filename ? filename : "");
  207. return bool(m_lib);
  208. }
  209. bool libClose()
  210. {
  211. if (m_lib)
  212. {
  213. const bool closed = lib_close(m_lib);
  214. m_lib = nullptr;
  215. return closed;
  216. }
  217. return false;
  218. }
  219. void* libSymbol(const char* const symbol)
  220. {
  221. if (m_lib)
  222. return lib_symbol(m_lib, symbol);
  223. return nullptr;
  224. }
  225. const char* libError()
  226. {
  227. return lib_error(m_filename);
  228. }
  229. #endif
  230. // ---------------------------------------------------------------------
  231. private:
  232. CarlaOsc m_osc;
  233. CarlaToolkit* const m_toolkit;
  234. struct {
  235. Message data[MAX_BRIDGE_MESSAGES];
  236. QMutex lock;
  237. } m_messages;
  238. #ifdef BUILD_BRIDGE_UI
  239. char* m_filename;
  240. void* m_lib;
  241. #endif
  242. };
  243. /**@}*/
  244. CARLA_BRIDGE_END_NAMESPACE
  245. #endif // CARLA_BRIDGE_CLIENT_H