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.

324 lines
12KB

  1. /*
  2. * Carla Bridge utils
  3. * Copyright (C) 2013-2019 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 kPluginBridgeNonRtServerParameterTouch:
  159. return "kPluginBridgeNonRtServerParameterTouch";
  160. case kPluginBridgeNonRtServerDefaultValue:
  161. return "kPluginBridgeNonRtServerDefaultValue";
  162. case kPluginBridgeNonRtServerCurrentProgram:
  163. return "kPluginBridgeNonRtServerCurrentProgram";
  164. case kPluginBridgeNonRtServerCurrentMidiProgram:
  165. return "kPluginBridgeNonRtServerCurrentMidiProgram";
  166. case kPluginBridgeNonRtServerProgramName:
  167. return "kPluginBridgeNonRtServerProgramName";
  168. case kPluginBridgeNonRtServerMidiProgramData:
  169. return "kPluginBridgeNonRtServerMidiProgramData";
  170. case kPluginBridgeNonRtServerSetCustomData:
  171. return "kPluginBridgeNonRtServerSetCustomData";
  172. case kPluginBridgeNonRtServerSetChunkDataFile:
  173. return "kPluginBridgeNonRtServerSetChunkDataFile";
  174. case kPluginBridgeNonRtServerSetLatency:
  175. return "kPluginBridgeNonRtServerSetLatency";
  176. case kPluginBridgeNonRtServerSetParameterText:
  177. return "kPluginBridgeNonRtServerSetParameterText";
  178. case kPluginBridgeNonRtServerReady:
  179. return "kPluginBridgeNonRtServerReady";
  180. case kPluginBridgeNonRtServerSaved:
  181. return "kPluginBridgeNonRtServerSaved";
  182. case kPluginBridgeNonRtServerUiClosed:
  183. return "kPluginBridgeNonRtServerUiClosed";
  184. case kPluginBridgeNonRtServerError:
  185. return "kPluginBridgeNonRtServerError";
  186. }
  187. carla_stderr("CarlaBackend::PluginBridgeNonRtServerOpcode2str%i) - invalid opcode", opcode);
  188. return nullptr;
  189. }
  190. // -------------------------------------------------------------------------------------------------------------------
  191. struct BridgeAudioPool {
  192. float* data;
  193. std::size_t dataSize;
  194. CarlaString filename;
  195. char shm[64];
  196. bool isServer;
  197. BridgeAudioPool() noexcept;
  198. ~BridgeAudioPool() noexcept;
  199. bool initializeServer() noexcept;
  200. bool attachClient(const char* const fname) noexcept;
  201. void clear() noexcept;
  202. void resize(const uint32_t bufferSize, const uint32_t audioPortCount, const uint32_t cvPortCount) noexcept;
  203. const char* getFilenameSuffix() const noexcept;
  204. CARLA_DECLARE_NON_COPY_STRUCT(BridgeAudioPool)
  205. };
  206. // -------------------------------------------------------------------------------------------------------------------
  207. struct BridgeRtClientControl : public CarlaRingBufferControl<SmallStackBuffer> {
  208. BridgeRtClientData* data;
  209. CarlaString filename;
  210. bool needsSemDestroy; // client only
  211. char shm[64];
  212. bool isServer;
  213. BridgeRtClientControl() noexcept;
  214. ~BridgeRtClientControl() noexcept override;
  215. bool initializeServer() noexcept;
  216. bool attachClient(const char* const basename) noexcept;
  217. void clear() noexcept;
  218. bool mapData() noexcept;
  219. void unmapData() noexcept;
  220. // non-bridge, server
  221. bool waitForClient(const uint msecs) noexcept;
  222. bool writeOpcode(const PluginBridgeRtClientOpcode opcode) noexcept;
  223. // bridge, client
  224. PluginBridgeRtClientOpcode readOpcode() noexcept;
  225. // helper class that automatically posts semaphore on destructor
  226. struct WaitHelper {
  227. BridgeRtClientData* const data;
  228. const bool ok;
  229. WaitHelper(BridgeRtClientControl& c) noexcept;
  230. ~WaitHelper() noexcept;
  231. CARLA_DECLARE_NON_COPY_STRUCT(WaitHelper)
  232. };
  233. CARLA_DECLARE_NON_COPY_STRUCT(BridgeRtClientControl)
  234. };
  235. // -------------------------------------------------------------------------------------------------------------------
  236. struct BridgeNonRtClientControl : public CarlaRingBufferControl<BigStackBuffer> {
  237. BridgeNonRtClientData* data;
  238. CarlaString filename;
  239. CarlaMutex mutex;
  240. char shm[64];
  241. bool isServer;
  242. BridgeNonRtClientControl() noexcept;
  243. ~BridgeNonRtClientControl() noexcept override;
  244. bool initializeServer() noexcept;
  245. bool attachClient(const char* const basename) noexcept;
  246. void clear() noexcept;
  247. bool mapData() noexcept;
  248. void unmapData() noexcept;
  249. // non-bridge, server
  250. void waitIfDataIsReachingLimit() noexcept;
  251. bool writeOpcode(const PluginBridgeNonRtClientOpcode opcode) noexcept;
  252. // bridge, client
  253. PluginBridgeNonRtClientOpcode readOpcode() noexcept;
  254. CARLA_DECLARE_NON_COPY_STRUCT(BridgeNonRtClientControl)
  255. };
  256. // -------------------------------------------------------------------------------------------------------------------
  257. struct BridgeNonRtServerControl : public CarlaRingBufferControl<HugeStackBuffer> {
  258. BridgeNonRtServerData* data;
  259. CarlaString filename;
  260. CarlaMutex mutex;
  261. char shm[64];
  262. bool isServer;
  263. BridgeNonRtServerControl() noexcept;
  264. ~BridgeNonRtServerControl() noexcept override;
  265. bool initializeServer() noexcept;
  266. bool attachClient(const char* const basename) noexcept;
  267. void clear() noexcept;
  268. bool mapData() noexcept;
  269. void unmapData() noexcept;
  270. // non-bridge, server
  271. PluginBridgeNonRtServerOpcode readOpcode() noexcept;
  272. // bridge, client
  273. void waitIfDataIsReachingLimit() noexcept;
  274. bool writeOpcode(const PluginBridgeNonRtServerOpcode opcode) noexcept;
  275. CARLA_DECLARE_NON_COPY_STRUCT(BridgeNonRtServerControl)
  276. };
  277. // -------------------------------------------------------------------------------------------------------------------
  278. #endif // CARLA_BRIDGE_UTILS_HPP_INCLUDED