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.

303 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 <cstdio>
  27. #include <cstdint>
  28. #include <cstdlib>
  29. #include <QtCore/QMutex>
  30. CARLA_BRIDGE_START_NAMESPACE
  31. /*!
  32. * @defgroup CarlaBridgeClient Carla Bridge Client
  33. *
  34. * The Carla Bridge Client.
  35. * @{
  36. */
  37. class CarlaClient
  38. {
  39. public:
  40. CarlaClient(CarlaToolkit* const toolkit)
  41. #ifdef BUILD_BRIDGE_PLUGIN
  42. : m_osc(this, "carla-bridge-plugin"),
  43. #else
  44. : m_osc(this, "carla-bridge-ui"),
  45. #endif
  46. m_toolkit(toolkit)
  47. {
  48. #ifdef BUILD_BRIDGE_UI
  49. m_filename = nullptr;
  50. m_lib = nullptr;
  51. #endif
  52. }
  53. virtual ~CarlaClient()
  54. {
  55. #ifdef BUILD_BRIDGE_UI
  56. if (m_filename)
  57. free(m_filename);
  58. #endif
  59. }
  60. // ---------------------------------------------------------------------
  61. void quequeMessage(const MessageType type, const int32_t value1, const int32_t value2, const double value3)
  62. {
  63. const QMutexLocker locker(&m_messages.lock);
  64. for (unsigned int i=0; i < MAX_BRIDGE_MESSAGES; i++)
  65. {
  66. Message* const m = &m_messages.data[i];
  67. if (m->type == MESSAGE_NULL)
  68. {
  69. m->type = type;
  70. m->value1 = value1;
  71. m->value2 = value2;
  72. m->value3 = value3;
  73. break;
  74. }
  75. }
  76. }
  77. bool runMessages()
  78. {
  79. const QMutexLocker locker(&m_messages.lock);
  80. for (unsigned int i=0; i < MAX_BRIDGE_MESSAGES; i++)
  81. {
  82. Message* const m = &m_messages.data[i];
  83. switch (m->type)
  84. {
  85. case MESSAGE_NULL:
  86. return true;
  87. case MESSAGE_PARAMETER:
  88. setParameter(m->value1, m->value3);
  89. break;
  90. case MESSAGE_PROGRAM:
  91. setProgram(m->value1);
  92. break;
  93. case MESSAGE_MIDI_PROGRAM:
  94. setMidiProgram(m->value1, m->value2);
  95. break;
  96. case MESSAGE_NOTE_ON:
  97. noteOn(m->value1, m->value2, rint(m->value3));
  98. break;
  99. case MESSAGE_NOTE_OFF:
  100. noteOff(m->value1, m->value2);
  101. break;
  102. case MESSAGE_SHOW_GUI:
  103. if (m->value1)
  104. m_toolkit->show();
  105. else
  106. m_toolkit->hide();
  107. break;
  108. case MESSAGE_RESIZE_GUI:
  109. m_toolkit->resize(m->value1, m->value2);
  110. break;
  111. case MESSAGE_SAVE_NOW:
  112. #ifdef BUILD_BRIDGE_PLUGIN
  113. saveNow();
  114. #endif
  115. break;
  116. case MESSAGE_QUIT:
  117. m_toolkit->quit();
  118. return false;
  119. }
  120. m->type = MESSAGE_NULL;
  121. }
  122. return true;
  123. }
  124. // ---------------------------------------------------------------------
  125. #ifdef BUILD_BRIDGE_UI
  126. // ui initialization
  127. virtual bool init(const char* const, const char* const) = 0;
  128. virtual void close() = 0;
  129. // ui management
  130. virtual void* getWidget() const = 0;
  131. virtual bool isResizable() const = 0;
  132. virtual bool needsReparent() const = 0;
  133. #endif
  134. // processing
  135. virtual void setParameter(const int32_t rindex, const double value) = 0;
  136. virtual void setProgram(const uint32_t index) = 0;
  137. virtual void setMidiProgram(const uint32_t bank, const uint32_t program) = 0;
  138. virtual void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) = 0;
  139. virtual void noteOff(const uint8_t channel, const uint8_t note) = 0;
  140. #ifdef BUILD_BRIDGE_PLUGIN
  141. // plugin
  142. virtual void saveNow() = 0;
  143. virtual void setCustomData(const char* const type, const char* const key, const char* const value) = 0;
  144. virtual void setChunkData(const char* const filePath) = 0;
  145. #endif
  146. // ---------------------------------------------------------------------
  147. bool oscInit(const char* const url)
  148. {
  149. qDebug("CarlaClient::oscInit(\"%s\")", url);
  150. return m_osc.init(url);
  151. }
  152. void oscClose()
  153. {
  154. qDebug("CarlaClient::oscClose()");
  155. m_osc.close();
  156. }
  157. #ifdef BUILD_BRIDGE_PLUGIN
  158. void registerOscEngine(CarlaBackend::CarlaEngine* const engine)
  159. {
  160. qDebug("CarlaClient::registerOscEngine(%p)", engine);
  161. engine->setOscBridgeData(m_osc.getControllerData());
  162. }
  163. #endif
  164. void sendOscConfigure(const char* const key, const char* const value)
  165. {
  166. qDebug("CarlaClient::sendOscConfigure(\"%s\", \"%s\")", key, value);
  167. m_osc.sendOscConfigure(key, value);
  168. }
  169. void sendOscControl(const int32_t index, const float value)
  170. {
  171. qDebug("CarlaClient::sendOscControl(%i, %f)", index, value);
  172. m_osc.sendOscControl(index, value);
  173. }
  174. void sendOscUpdate()
  175. {
  176. qDebug("CarlaClient::sendOscUpdate()");
  177. m_osc.sendOscUpdate();
  178. }
  179. void sendOscExiting()
  180. {
  181. qDebug("CarlaClient::sendOscExiting()");
  182. m_osc.sendOscExiting();
  183. }
  184. #ifdef BRIDGE_LV2
  185. void sendOscLv2TransferAtom(const char* const type, const char* const value)
  186. {
  187. qDebug("CarlaClient::sendOscLv2TransferAtom(\"%s\", \"%s\")", type, value);
  188. m_osc.sendOscLv2TransferAtom(type, value);
  189. }
  190. void sendOscLv2TransferEvent(const char* const type, const char* const value)
  191. {
  192. qDebug("CarlaClient::sendOscLv2TransferEvent(\"%s\", \"%s\")", type, value);
  193. m_osc.sendOscLv2TransferEvent(type, value);
  194. }
  195. #endif
  196. // ---------------------------------------------------------------------
  197. #ifdef BUILD_BRIDGE_UI
  198. protected:
  199. bool libOpen(const char* const filename)
  200. {
  201. Q_ASSERT(filename);
  202. if (m_filename)
  203. free(m_filename);
  204. m_lib = lib_open(filename);
  205. m_filename = strdup(filename ? filename : "");
  206. return bool(m_lib);
  207. }
  208. bool libClose()
  209. {
  210. if (m_lib)
  211. {
  212. const bool closed = lib_close(m_lib);
  213. m_lib = nullptr;
  214. return closed;
  215. }
  216. return false;
  217. }
  218. void* libSymbol(const char* const symbol)
  219. {
  220. if (m_lib)
  221. return lib_symbol(m_lib, symbol);
  222. return nullptr;
  223. }
  224. const char* libError()
  225. {
  226. return lib_error(m_filename);
  227. }
  228. #endif
  229. // ---------------------------------------------------------------------
  230. private:
  231. CarlaOsc m_osc;
  232. CarlaToolkit* const m_toolkit;
  233. struct {
  234. Message data[MAX_BRIDGE_MESSAGES];
  235. QMutex lock;
  236. } m_messages;
  237. #ifdef BUILD_BRIDGE_UI
  238. char* m_filename;
  239. void* m_lib;
  240. #endif
  241. };
  242. /**@}*/
  243. CARLA_BRIDGE_END_NAMESPACE
  244. #endif // CARLA_BRIDGE_CLIENT_H