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.

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