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.

266 lines
6.5KB

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