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.

CarlaBridgeUtils.hpp 15KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  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