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.

341 lines
15KB

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