Audio plugin host https://kx.studio/carla
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.

322 lines
12KB

  1. /*
  2. * Carla Bridge utils
  3. * Copyright (C) 2013-2018 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or 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 doc/GPL.txt file.
  16. */
  17. #ifndef CARLA_BRIDGE_UTILS_HPP_INCLUDED
  18. #define CARLA_BRIDGE_UTILS_HPP_INCLUDED
  19. #include "CarlaBridgeDefines.hpp"
  20. #include "CarlaMutex.hpp"
  21. #include "CarlaString.hpp"
  22. // -------------------------------------------------------------------------------------------------------------------
  23. static inline
  24. const char* PluginBridgeRtClientOpcode2str(const PluginBridgeRtClientOpcode opcode) noexcept
  25. {
  26. switch (opcode)
  27. {
  28. case kPluginBridgeRtClientNull:
  29. return "kPluginBridgeRtClientNull";
  30. case kPluginBridgeRtClientSetAudioPool:
  31. return "kPluginBridgeRtClientSetAudioPool";
  32. case kPluginBridgeRtClientSetBufferSize:
  33. return "kPluginBridgeRtClientSetBufferSize";
  34. case kPluginBridgeRtClientSetSampleRate:
  35. return "kPluginBridgeRtClientSetSampleRate";
  36. case kPluginBridgeRtClientSetOnline:
  37. return "kPluginBridgeRtClientSetOnline";
  38. case kPluginBridgeRtClientControlEventParameter:
  39. return "kPluginBridgeRtClientControlEventParameter";
  40. case kPluginBridgeRtClientControlEventMidiBank:
  41. return "kPluginBridgeRtClientControlEventMidiBank";
  42. case kPluginBridgeRtClientControlEventMidiProgram:
  43. return "kPluginBridgeRtClientControlEventMidiProgram";
  44. case kPluginBridgeRtClientControlEventAllSoundOff:
  45. return "kPluginBridgeRtClientControlEventAllSoundOff";
  46. case kPluginBridgeRtClientControlEventAllNotesOff:
  47. return "kPluginBridgeRtClientControlEventAllNotesOff";
  48. case kPluginBridgeRtClientMidiEvent:
  49. return "kPluginBridgeRtClientMidiEvent";
  50. case kPluginBridgeRtClientProcess:
  51. return "kPluginBridgeRtClientProcess";
  52. case kPluginBridgeRtClientQuit:
  53. return "kPluginBridgeRtClientQuit";
  54. }
  55. carla_stderr("CarlaBackend::PluginBridgeRtClientOpcode2str(%i) - invalid opcode", opcode);
  56. return nullptr;
  57. }
  58. static inline
  59. const char* PluginBridgeNonRtClientOpcode2str(const PluginBridgeNonRtClientOpcode opcode) noexcept
  60. {
  61. switch (opcode)
  62. {
  63. case kPluginBridgeNonRtClientNull:
  64. return "kPluginBridgeNonRtClientNull";
  65. case kPluginBridgeNonRtClientVersion:
  66. return "kPluginBridgeNonRtClientVersion";
  67. case kPluginBridgeNonRtClientPing:
  68. return "kPluginBridgeNonRtClientPing";
  69. case kPluginBridgeNonRtClientPingOnOff:
  70. return "kPluginBridgeNonRtClientPingOnOff";
  71. case kPluginBridgeNonRtClientActivate:
  72. return "kPluginBridgeNonRtClientActivate";
  73. case kPluginBridgeNonRtClientDeactivate:
  74. return "kPluginBridgeNonRtClientDeactivate";
  75. case kPluginBridgeNonRtClientInitialSetup:
  76. return "kPluginBridgeNonRtClientInitialSetup";
  77. case kPluginBridgeNonRtClientSetParameterValue:
  78. return "kPluginBridgeNonRtClientSetParameterValue";
  79. case kPluginBridgeNonRtClientSetParameterMidiChannel:
  80. return "kPluginBridgeNonRtClientSetParameterMidiChannel";
  81. case kPluginBridgeNonRtClientSetParameterMidiCC:
  82. return "kPluginBridgeNonRtClientSetParameterMidiCC";
  83. case kPluginBridgeNonRtClientSetProgram:
  84. return "kPluginBridgeNonRtClientSetProgram";
  85. case kPluginBridgeNonRtClientSetMidiProgram:
  86. return "kPluginBridgeNonRtClientSetMidiProgram";
  87. case kPluginBridgeNonRtClientSetCustomData:
  88. return "kPluginBridgeNonRtClientSetCustomData";
  89. case kPluginBridgeNonRtClientSetChunkDataFile:
  90. return "kPluginBridgeNonRtClientSetChunkDataFile";
  91. case kPluginBridgeNonRtClientSetCtrlChannel:
  92. return "kPluginBridgeNonRtClientSetCtrlChannel";
  93. case kPluginBridgeNonRtClientSetOption:
  94. return "kPluginBridgeNonRtClientSetOption";
  95. case kPluginBridgeNonRtClientGetParameterText:
  96. return "kPluginBridgeNonRtClientGetParameterText";
  97. case kPluginBridgeNonRtClientPrepareForSave:
  98. return "kPluginBridgeNonRtClientPrepareForSave";
  99. case kPluginBridgeNonRtClientRestoreLV2State:
  100. return "kPluginBridgeNonRtClientRestoreLV2State";
  101. case kPluginBridgeNonRtClientShowUI:
  102. return "kPluginBridgeNonRtClientShowUI";
  103. case kPluginBridgeNonRtClientHideUI:
  104. return "kPluginBridgeNonRtClientHideUI";
  105. case kPluginBridgeNonRtClientUiParameterChange:
  106. return "kPluginBridgeNonRtClientUiParameterChange";
  107. case kPluginBridgeNonRtClientUiProgramChange:
  108. return "kPluginBridgeNonRtClientUiProgramChange";
  109. case kPluginBridgeNonRtClientUiMidiProgramChange:
  110. return "kPluginBridgeNonRtClientUiMidiProgramChange";
  111. case kPluginBridgeNonRtClientUiNoteOn:
  112. return "kPluginBridgeNonRtClientUiNoteOn";
  113. case kPluginBridgeNonRtClientUiNoteOff:
  114. return "kPluginBridgeNonRtClientUiNoteOff";
  115. case kPluginBridgeNonRtClientQuit:
  116. return "kPluginBridgeNonRtClientQuit";
  117. }
  118. carla_stderr("CarlaBackend::PluginBridgeNonRtClientOpcode2str(%i) - invalid opcode", opcode);
  119. return nullptr;
  120. }
  121. static inline
  122. const char* PluginBridgeNonRtServerOpcode2str(const PluginBridgeNonRtServerOpcode opcode) noexcept
  123. {
  124. switch (opcode)
  125. {
  126. case kPluginBridgeNonRtServerNull:
  127. return "kPluginBridgeNonRtServerNull";
  128. case kPluginBridgeNonRtServerPong:
  129. return "kPluginBridgeNonRtServerPong";
  130. case kPluginBridgeNonRtServerPluginInfo1:
  131. return "kPluginBridgeNonRtServerPluginInfo1";
  132. case kPluginBridgeNonRtServerPluginInfo2:
  133. return "kPluginBridgeNonRtServerPluginInfo2";
  134. case kPluginBridgeNonRtServerAudioCount:
  135. return "kPluginBridgeNonRtServerAudioCount";
  136. case kPluginBridgeNonRtServerMidiCount:
  137. return "kPluginBridgeNonRtServerMidiCount";
  138. case kPluginBridgeNonRtServerCvCount:
  139. return "kPluginBridgeNonRtServerCvCount";
  140. case kPluginBridgeNonRtServerParameterCount:
  141. return "kPluginBridgeNonRtServerParameterCount";
  142. case kPluginBridgeNonRtServerProgramCount:
  143. return "kPluginBridgeNonRtServerProgramCount";
  144. case kPluginBridgeNonRtServerMidiProgramCount:
  145. return "kPluginBridgeNonRtServerMidiProgramCount";
  146. case kPluginBridgeNonRtServerPortName:
  147. return "kPluginBridgeNonRtServerPortName";
  148. case kPluginBridgeNonRtServerParameterData1:
  149. return "kPluginBridgeNonRtServerParameterData1";
  150. case kPluginBridgeNonRtServerParameterData2:
  151. return "kPluginBridgeNonRtServerParameterData2";
  152. case kPluginBridgeNonRtServerParameterRanges:
  153. return "kPluginBridgeNonRtServerParameterRanges";
  154. case kPluginBridgeNonRtServerParameterValue:
  155. return "kPluginBridgeNonRtServerParameterValue";
  156. case kPluginBridgeNonRtServerParameterValue2:
  157. return "kPluginBridgeNonRtServerParameterValue2";
  158. case kPluginBridgeNonRtServerDefaultValue:
  159. return "kPluginBridgeNonRtServerDefaultValue";
  160. case kPluginBridgeNonRtServerCurrentProgram:
  161. return "kPluginBridgeNonRtServerCurrentProgram";
  162. case kPluginBridgeNonRtServerCurrentMidiProgram:
  163. return "kPluginBridgeNonRtServerCurrentMidiProgram";
  164. case kPluginBridgeNonRtServerProgramName:
  165. return "kPluginBridgeNonRtServerProgramName";
  166. case kPluginBridgeNonRtServerMidiProgramData:
  167. return "kPluginBridgeNonRtServerMidiProgramData";
  168. case kPluginBridgeNonRtServerSetCustomData:
  169. return "kPluginBridgeNonRtServerSetCustomData";
  170. case kPluginBridgeNonRtServerSetChunkDataFile:
  171. return "kPluginBridgeNonRtServerSetChunkDataFile";
  172. case kPluginBridgeNonRtServerSetLatency:
  173. return "kPluginBridgeNonRtServerSetLatency";
  174. case kPluginBridgeNonRtServerSetParameterText:
  175. return "kPluginBridgeNonRtServerSetParameterText";
  176. case kPluginBridgeNonRtServerReady:
  177. return "kPluginBridgeNonRtServerReady";
  178. case kPluginBridgeNonRtServerSaved:
  179. return "kPluginBridgeNonRtServerSaved";
  180. case kPluginBridgeNonRtServerUiClosed:
  181. return "kPluginBridgeNonRtServerUiClosed";
  182. case kPluginBridgeNonRtServerError:
  183. return "kPluginBridgeNonRtServerError";
  184. }
  185. carla_stderr("CarlaBackend::PluginBridgeNonRtServerOpcode2str%i) - invalid opcode", opcode);
  186. return nullptr;
  187. }
  188. // -------------------------------------------------------------------------------------------------------------------
  189. struct BridgeAudioPool {
  190. float* data;
  191. std::size_t dataSize;
  192. CarlaString filename;
  193. char shm[64];
  194. bool isServer;
  195. BridgeAudioPool() noexcept;
  196. ~BridgeAudioPool() noexcept;
  197. bool initializeServer() noexcept;
  198. bool attachClient(const char* const fname) noexcept;
  199. void clear() noexcept;
  200. void resize(const uint32_t bufferSize, const uint32_t audioPortCount, const uint32_t cvPortCount) noexcept;
  201. const char* getFilenameSuffix() const noexcept;
  202. CARLA_DECLARE_NON_COPY_STRUCT(BridgeAudioPool)
  203. };
  204. // -------------------------------------------------------------------------------------------------------------------
  205. struct BridgeRtClientControl : public CarlaRingBufferControl<SmallStackBuffer> {
  206. BridgeRtClientData* data;
  207. CarlaString filename;
  208. bool needsSemDestroy; // client only
  209. char shm[64];
  210. bool isServer;
  211. BridgeRtClientControl() noexcept;
  212. ~BridgeRtClientControl() noexcept override;
  213. bool initializeServer() noexcept;
  214. bool attachClient(const char* const basename) noexcept;
  215. void clear() noexcept;
  216. bool mapData() noexcept;
  217. void unmapData() noexcept;
  218. // non-bridge, server
  219. bool waitForClient(const uint msecs) noexcept;
  220. bool writeOpcode(const PluginBridgeRtClientOpcode opcode) noexcept;
  221. // bridge, client
  222. PluginBridgeRtClientOpcode readOpcode() noexcept;
  223. // helper class that automatically posts semaphore on destructor
  224. struct WaitHelper {
  225. BridgeRtClientData* const data;
  226. const bool ok;
  227. WaitHelper(BridgeRtClientControl& c) noexcept;
  228. ~WaitHelper() noexcept;
  229. CARLA_DECLARE_NON_COPY_STRUCT(WaitHelper)
  230. };
  231. CARLA_DECLARE_NON_COPY_STRUCT(BridgeRtClientControl)
  232. };
  233. // -------------------------------------------------------------------------------------------------------------------
  234. struct BridgeNonRtClientControl : public CarlaRingBufferControl<BigStackBuffer> {
  235. BridgeNonRtClientData* data;
  236. CarlaString filename;
  237. CarlaMutex mutex;
  238. char shm[64];
  239. bool isServer;
  240. BridgeNonRtClientControl() noexcept;
  241. ~BridgeNonRtClientControl() noexcept override;
  242. bool initializeServer() noexcept;
  243. bool attachClient(const char* const basename) noexcept;
  244. void clear() noexcept;
  245. bool mapData() noexcept;
  246. void unmapData() noexcept;
  247. // non-bridge, server
  248. void waitIfDataIsReachingLimit() noexcept;
  249. bool writeOpcode(const PluginBridgeNonRtClientOpcode opcode) noexcept;
  250. // bridge, client
  251. PluginBridgeNonRtClientOpcode readOpcode() noexcept;
  252. CARLA_DECLARE_NON_COPY_STRUCT(BridgeNonRtClientControl)
  253. };
  254. // -------------------------------------------------------------------------------------------------------------------
  255. struct BridgeNonRtServerControl : public CarlaRingBufferControl<HugeStackBuffer> {
  256. BridgeNonRtServerData* data;
  257. CarlaString filename;
  258. CarlaMutex mutex;
  259. char shm[64];
  260. bool isServer;
  261. BridgeNonRtServerControl() noexcept;
  262. ~BridgeNonRtServerControl() noexcept override;
  263. bool initializeServer() noexcept;
  264. bool attachClient(const char* const basename) noexcept;
  265. void clear() noexcept;
  266. bool mapData() noexcept;
  267. void unmapData() noexcept;
  268. // non-bridge, server
  269. PluginBridgeNonRtServerOpcode readOpcode() noexcept;
  270. // bridge, client
  271. void waitIfDataIsReachingLimit() noexcept;
  272. bool writeOpcode(const PluginBridgeNonRtServerOpcode opcode) noexcept;
  273. CARLA_DECLARE_NON_COPY_STRUCT(BridgeNonRtServerControl)
  274. };
  275. // -------------------------------------------------------------------------------------------------------------------
  276. #endif // CARLA_BRIDGE_UTILS_HPP_INCLUDED