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.

320 lines
14KB

  1. /*
  2. * Carla Bridge utils
  3. * Copyright (C) 2013-2014 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 "CarlaRingBuffer.hpp"
  20. #if defined(CARLA_OS_WIN) && defined(BUILDING_CARLA_FOR_WINDOWS)
  21. # define PLUGIN_BRIDGE_NAMEPREFIX_AUDIO_POOL "Global\\carla-bridge_shm_ap_"
  22. # define PLUGIN_BRIDGE_NAMEPREFIX_RT_CLIENT "Global\\carla-bridge_shm_rtC_"
  23. # define PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_CLIENT "Global\\carla-bridge_shm_nonrtC_"
  24. # define PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_SERVER "Global\\carla-bridge_shm_nonrtS_"
  25. #else
  26. # define PLUGIN_BRIDGE_NAMEPREFIX_AUDIO_POOL "/carla-bridge_shm_ap_"
  27. # define PLUGIN_BRIDGE_NAMEPREFIX_RT_CLIENT "/carla-bridge_shm_rtC_"
  28. # define PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_CLIENT "/carla-bridge_shm_nonrtC_"
  29. # define PLUGIN_BRIDGE_NAMEPREFIX_NON_RT_SERVER "/carla-bridge_shm_nonrtS_"
  30. #endif
  31. // -----------------------------------------------------------------------
  32. // Server sends these to client during RT
  33. enum PluginBridgeRtClientOpcode {
  34. kPluginBridgeRtClientNull = 0,
  35. kPluginBridgeRtClientSetAudioPool, // ulong/ptr
  36. kPluginBridgeRtClientControlEventParameter, // uint/frame, byte/chan, ushort, float
  37. kPluginBridgeRtClientControlEventMidiBank, // uint/frame, byte/chan, ushort
  38. kPluginBridgeRtClientControlEventMidiProgram, // uint/frame, byte/chan, ushort
  39. kPluginBridgeRtClientControlEventAllSoundOff, // uint/frame, byte/chan
  40. kPluginBridgeRtClientControlEventAllNotesOff, // uint/frame, byte/chan
  41. kPluginBridgeRtClientMidiEvent, // uint/frame, byte/port, byte/size, byte[]/data
  42. kPluginBridgeRtClientProcess,
  43. kPluginBridgeRtClientQuit
  44. };
  45. // Server sends these to client during non-RT
  46. enum PluginBridgeNonRtClientOpcode {
  47. kPluginBridgeNonRtClientNull = 0,
  48. kPluginBridgeNonRtClientPing,
  49. kPluginBridgeNonRtClientActivate,
  50. kPluginBridgeNonRtClientDeactivate,
  51. kPluginBridgeNonRtClientSetBufferSize, // uint
  52. kPluginBridgeNonRtClientSetSampleRate, // double
  53. kPluginBridgeNonRtClientSetOffline,
  54. kPluginBridgeNonRtClientSetOnline,
  55. kPluginBridgeNonRtClientSetParameterValue, // uint, float
  56. kPluginBridgeNonRtClientSetParameterMidiChannel, // uint, byte
  57. kPluginBridgeNonRtClientSetParameterMidiCC, // uint, short
  58. kPluginBridgeNonRtClientSetProgram, // int
  59. kPluginBridgeNonRtClientSetMidiProgram, // int
  60. kPluginBridgeNonRtClientSetCustomData, // uint/size, str[], uint/size, str[], uint/size, str[]
  61. kPluginBridgeNonRtClientSetChunkDataFile, // uint/size, str[] (filename, base64 content)
  62. kPluginBridgeNonRtClientSetCtrlChannel, // short
  63. kPluginBridgeNonRtClientSetOption, // uint/option, bool
  64. kPluginBridgeNonRtClientPrepareForSave,
  65. kPluginBridgeNonRtClientShowUI,
  66. kPluginBridgeNonRtClientHideUI,
  67. kPluginBridgeNonRtClientUiParameterChange, // uint, float
  68. kPluginBridgeNonRtClientUiProgramChange, // uint
  69. kPluginBridgeNonRtClientUiMidiProgramChange, // uint
  70. kPluginBridgeNonRtClientUiNoteOn, // byte, byte, byte
  71. kPluginBridgeNonRtClientUiNoteOff, // byte, byte
  72. kPluginBridgeNonRtClientQuit
  73. };
  74. // Client sends these to server during non-RT
  75. enum PluginBridgeNonRtServerOpcode {
  76. kPluginBridgeNonRtServerNull = 0,
  77. kPluginBridgeNonRtServerPong,
  78. kPluginBridgeNonRtServerPluginInfo1, // uint/category, uint/hints, uint/optionsAvailable, uint/optionsEnabled, long/uniqueId
  79. kPluginBridgeNonRtServerPluginInfo2, // uint/size, str[] (realName), uint/size, str[] (label), uint/size, str[] (maker), uint/size, str[] (copyright)
  80. kPluginBridgeNonRtServerAudioCount, // uint/ins, uint/outs
  81. kPluginBridgeNonRtServerMidiCount, // uint/ins, uint/outs
  82. kPluginBridgeNonRtServerParameterCount, // uint/count
  83. kPluginBridgeNonRtServerProgramCount, // uint/count
  84. kPluginBridgeNonRtServerMidiProgramCount, // uint/count
  85. kPluginBridgeNonRtServerParameterData1, // uint/index, int/rindex, uint/type, uint/hints, short/cc
  86. kPluginBridgeNonRtServerParameterData2, // uint/index, uint/size, str[] (name), uint/size, str[] (symbol), uint/size, str[] (unit)
  87. kPluginBridgeNonRtServerParameterRanges, // uint/index, float/def, float/min, float/max, float/step, float/stepSmall, float/stepLarge
  88. kPluginBridgeNonRtServerParameterValue, // uint/index, float/value
  89. kPluginBridgeNonRtServerParameterValue2, // uint/index, float/value (used for init/output parameters only, don't resend values)
  90. kPluginBridgeNonRtServerDefaultValue, // uint/index, float/value
  91. kPluginBridgeNonRtServerCurrentProgram, // int/index
  92. kPluginBridgeNonRtServerCurrentMidiProgram, // int/index
  93. kPluginBridgeNonRtServerProgramName, // uint/index, uint/size, str[] (name)
  94. kPluginBridgeNonRtServerMidiProgramData, // uint/index, uint/bank, uint/program, uint/size, str[] (name)
  95. kPluginBridgeNonRtServerSetCustomData, // uint/size, str[], uint/size, str[], uint/size, str[]
  96. kPluginBridgeNonRtServerSetChunkDataFile, // uint/size, str[] (filename, base64 content)
  97. kPluginBridgeNonRtServerSetLatency, // uint
  98. kPluginBridgeNonRtServerReady,
  99. kPluginBridgeNonRtServerSaved,
  100. kPluginBridgeNonRtServerUiClosed,
  101. kPluginBridgeNonRtServerError // uint/size, str[]
  102. };
  103. // -----------------------------------------------------------------------
  104. struct BridgeSemaphore {
  105. union {
  106. void* server;
  107. char _padServer[64];
  108. };
  109. union {
  110. void* client;
  111. char _padClient[64];
  112. };
  113. };
  114. // needs to be 64bit aligned
  115. struct BridgeTimeInfo {
  116. uint64_t playing;
  117. uint64_t frame;
  118. uint64_t usecs;
  119. uint32_t valid;
  120. // bbt
  121. int32_t bar, beat, tick;
  122. float beatsPerBar, beatType;
  123. double barStartTick, ticksPerBeat, beatsPerMinute;
  124. };
  125. // -----------------------------------------------------------------------
  126. static const std::size_t kBridgeRtClientDataMidiOutSize = 512*4;
  127. // Server => Client RT
  128. struct BridgeRtClientData {
  129. BridgeSemaphore sem;
  130. BridgeTimeInfo timeInfo;
  131. SmallStackBuffer ringBuffer;
  132. uint8_t midiOut[kBridgeRtClientDataMidiOutSize];
  133. };
  134. // Server => Client Non-RT
  135. struct BridgeNonRtClientData {
  136. BigStackBuffer ringBuffer;
  137. };
  138. // Client => Server Non-RT
  139. struct BridgeNonRtServerData {
  140. HugeStackBuffer ringBuffer;
  141. };
  142. // -----------------------------------------------------------------------
  143. static inline
  144. const char* PluginBridgeRtClientOpcode2str(const PluginBridgeRtClientOpcode opcode) noexcept
  145. {
  146. switch (opcode)
  147. {
  148. case kPluginBridgeRtClientNull:
  149. return "kPluginBridgeRtClientNull";
  150. case kPluginBridgeRtClientSetAudioPool:
  151. return "kPluginBridgeRtClientSetAudioPool";
  152. case kPluginBridgeRtClientControlEventParameter:
  153. return "kPluginBridgeRtClientControlEventParameter";
  154. case kPluginBridgeRtClientControlEventMidiBank:
  155. return "kPluginBridgeRtClientControlEventMidiBank";
  156. case kPluginBridgeRtClientControlEventMidiProgram:
  157. return "kPluginBridgeRtClientControlEventMidiProgram";
  158. case kPluginBridgeRtClientControlEventAllSoundOff:
  159. return "kPluginBridgeRtClientControlEventAllSoundOff";
  160. case kPluginBridgeRtClientControlEventAllNotesOff:
  161. return "kPluginBridgeRtClientControlEventAllNotesOff";
  162. case kPluginBridgeRtClientMidiEvent:
  163. return "kPluginBridgeRtClientMidiEvent";
  164. case kPluginBridgeRtClientProcess:
  165. return "kPluginBridgeRtClientProcess";
  166. case kPluginBridgeRtClientQuit:
  167. return "kPluginBridgeRtClientQuit";
  168. }
  169. carla_stderr("CarlaBackend::PluginBridgeRtClientOpcode2str(%i) - invalid opcode", opcode);
  170. return nullptr;
  171. }
  172. static inline
  173. const char* PluginBridgeNonRtClientOpcode2str(const PluginBridgeNonRtClientOpcode opcode) noexcept
  174. {
  175. switch (opcode)
  176. {
  177. case kPluginBridgeNonRtClientNull:
  178. return "kPluginBridgeNonRtClientNull";
  179. case kPluginBridgeNonRtClientPing:
  180. return "kPluginBridgeNonRtClientPing";
  181. case kPluginBridgeNonRtClientActivate:
  182. return "kPluginBridgeNonRtClientActivate";
  183. case kPluginBridgeNonRtClientDeactivate:
  184. return "kPluginBridgeNonRtClientDeactivate";
  185. case kPluginBridgeNonRtClientSetBufferSize:
  186. return "kPluginBridgeNonRtClientSetBufferSize";
  187. case kPluginBridgeNonRtClientSetSampleRate:
  188. return "kPluginBridgeNonRtClientSetSampleRate";
  189. case kPluginBridgeNonRtClientSetOffline:
  190. return "kPluginBridgeNonRtClientSetOffline";
  191. case kPluginBridgeNonRtClientSetOnline:
  192. return "kPluginBridgeNonRtClientSetOnline";
  193. case kPluginBridgeNonRtClientSetParameterValue:
  194. return "kPluginBridgeNonRtClientSetParameterValue";
  195. case kPluginBridgeNonRtClientSetParameterMidiChannel:
  196. return "kPluginBridgeNonRtClientSetParameterMidiChannel";
  197. case kPluginBridgeNonRtClientSetParameterMidiCC:
  198. return "kPluginBridgeNonRtClientSetParameterMidiCC";
  199. case kPluginBridgeNonRtClientSetProgram:
  200. return "kPluginBridgeNonRtClientSetProgram";
  201. case kPluginBridgeNonRtClientSetMidiProgram:
  202. return "kPluginBridgeNonRtClientSetMidiProgram";
  203. case kPluginBridgeNonRtClientSetCustomData:
  204. return "kPluginBridgeNonRtClientSetCustomData";
  205. case kPluginBridgeNonRtClientSetChunkDataFile:
  206. return "kPluginBridgeNonRtClientSetChunkDataFile";
  207. case kPluginBridgeNonRtClientSetCtrlChannel:
  208. return "kPluginBridgeNonRtClientSetCtrlChannel";
  209. case kPluginBridgeNonRtClientSetOption:
  210. return "kPluginBridgeNonRtClientSetOption";
  211. case kPluginBridgeNonRtClientPrepareForSave:
  212. return "kPluginBridgeNonRtClientPrepareForSave";
  213. case kPluginBridgeNonRtClientShowUI:
  214. return "kPluginBridgeNonRtClientShowUI";
  215. case kPluginBridgeNonRtClientHideUI:
  216. return "kPluginBridgeNonRtClientHideUI";
  217. case kPluginBridgeNonRtClientUiParameterChange:
  218. return "kPluginBridgeNonRtClientUiParameterChange";
  219. case kPluginBridgeNonRtClientUiProgramChange:
  220. return "kPluginBridgeNonRtClientUiProgramChange";
  221. case kPluginBridgeNonRtClientUiMidiProgramChange:
  222. return "kPluginBridgeNonRtClientUiMidiProgramChange";
  223. case kPluginBridgeNonRtClientUiNoteOn:
  224. return "kPluginBridgeNonRtClientUiNoteOn";
  225. case kPluginBridgeNonRtClientUiNoteOff:
  226. return "kPluginBridgeNonRtClientUiNoteOff";
  227. case kPluginBridgeNonRtClientQuit:
  228. return "kPluginBridgeNonRtClientQuit";
  229. }
  230. carla_stderr("CarlaBackend::PluginBridgeNonRtClientOpcode2str(%i) - invalid opcode", opcode);
  231. return nullptr;
  232. }
  233. static inline
  234. const char* PluginBridgeNonRtServerOpcode2str(const PluginBridgeNonRtServerOpcode opcode) noexcept
  235. {
  236. switch (opcode)
  237. {
  238. case kPluginBridgeNonRtServerNull:
  239. return "kPluginBridgeNonRtServerNull";
  240. case kPluginBridgeNonRtServerPong:
  241. return "kPluginBridgeNonRtServerPong";
  242. case kPluginBridgeNonRtServerPluginInfo1:
  243. return "kPluginBridgeNonRtServerPluginInfo1";
  244. case kPluginBridgeNonRtServerPluginInfo2:
  245. return "kPluginBridgeNonRtServerPluginInfo2";
  246. case kPluginBridgeNonRtServerAudioCount:
  247. return "kPluginBridgeNonRtServerAudioCount";
  248. case kPluginBridgeNonRtServerMidiCount:
  249. return "kPluginBridgeNonRtServerMidiCount";
  250. case kPluginBridgeNonRtServerParameterCount:
  251. return "kPluginBridgeNonRtServerParameterCount";
  252. case kPluginBridgeNonRtServerProgramCount:
  253. return "kPluginBridgeNonRtServerProgramCount";
  254. case kPluginBridgeNonRtServerMidiProgramCount:
  255. return "kPluginBridgeNonRtServerMidiProgramCount";
  256. case kPluginBridgeNonRtServerParameterData1:
  257. return "kPluginBridgeNonRtServerParameterData1";
  258. case kPluginBridgeNonRtServerParameterData2:
  259. return "kPluginBridgeNonRtServerParameterData2";
  260. case kPluginBridgeNonRtServerParameterRanges:
  261. return "kPluginBridgeNonRtServerParameterRanges";
  262. case kPluginBridgeNonRtServerParameterValue:
  263. return "kPluginBridgeNonRtServerParameterValue";
  264. case kPluginBridgeNonRtServerParameterValue2:
  265. return "kPluginBridgeNonRtServerParameterValue2";
  266. case kPluginBridgeNonRtServerDefaultValue:
  267. return "kPluginBridgeNonRtServerDefaultValue";
  268. case kPluginBridgeNonRtServerCurrentProgram:
  269. return "kPluginBridgeNonRtServerCurrentProgram";
  270. case kPluginBridgeNonRtServerCurrentMidiProgram:
  271. return "kPluginBridgeNonRtServerCurrentMidiProgram";
  272. case kPluginBridgeNonRtServerProgramName:
  273. return "kPluginBridgeNonRtServerProgramName";
  274. case kPluginBridgeNonRtServerMidiProgramData:
  275. return "kPluginBridgeNonRtServerMidiProgramData";
  276. case kPluginBridgeNonRtServerSetCustomData:
  277. return "kPluginBridgeNonRtServerSetCustomData";
  278. case kPluginBridgeNonRtServerSetChunkDataFile:
  279. return "kPluginBridgeNonRtServerSetChunkDataFile";
  280. case kPluginBridgeNonRtServerSetLatency:
  281. return "kPluginBridgeNonRtServerSetLatency";
  282. case kPluginBridgeNonRtServerReady:
  283. return "kPluginBridgeNonRtServerReady";
  284. case kPluginBridgeNonRtServerSaved:
  285. return "kPluginBridgeNonRtServerSaved";
  286. case kPluginBridgeNonRtServerUiClosed:
  287. return "kPluginBridgeNonRtServerUiClosed";
  288. case kPluginBridgeNonRtServerError:
  289. return "kPluginBridgeNonRtServerError";
  290. }
  291. carla_stderr("CarlaBackend::PluginBridgeNonRtServerOpcode2str%i) - invalid opcode", opcode);
  292. return nullptr;
  293. }
  294. // -----------------------------------------------------------------------
  295. #endif // CARLA_BRIDGE_UTILS_HPP_INCLUDED