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.

413 lines
11KB

  1. /*
  2. * Carla Plugin
  3. * Copyright (C) 2011-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_PLUGIN_INTERNAL_HPP_INCLUDED
  18. #define CARLA_PLUGIN_INTERNAL_HPP_INCLUDED
  19. #include "CarlaPlugin.hpp"
  20. #include "CarlaJuceUtils.hpp"
  21. #include "CarlaLibUtils.hpp"
  22. #include "CarlaStateUtils.hpp"
  23. #include "CarlaMIDI.h"
  24. #include "CarlaMutex.hpp"
  25. #include "CarlaString.hpp"
  26. #include "RtLinkedList.hpp"
  27. CARLA_BACKEND_START_NAMESPACE
  28. // -----------------------------------------------------------------------
  29. // Engine helper macro, sets lastError and returns false/NULL
  30. #define CARLA_SAFE_ASSERT_RETURN_ERR(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); pData->engine->setLastError(err); return false; }
  31. #define CARLA_SAFE_ASSERT_RETURN_ERRN(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); pData->engine->setLastError(err); return nullptr; }
  32. #define CARLA_SAFE_EXCEPTION_RETURN_ERR(excptMsg, errMsg) catch(...) { carla_safe_exception(excptMsg, __FILE__, __LINE__); pData->engine->setLastError(errMsg); return false; }
  33. #define CARLA_SAFE_EXCEPTION_RETURN_ERRN(excptMsg, errMsg) catch(...) { carla_safe_exception(excptMsg, __FILE__, __LINE__); pData->engine->setLastError(errMsg); return nullptr; }
  34. // -----------------------------------------------------------------------
  35. // Maximum pre-allocated events for some plugin types
  36. const ushort kPluginMaxMidiEvents = 512;
  37. // -----------------------------------------------------------------------
  38. // Extra plugin hints, hidden from backend
  39. const uint PLUGIN_EXTRA_HINT_HAS_MIDI_IN = 0x01;
  40. const uint PLUGIN_EXTRA_HINT_HAS_MIDI_OUT = 0x02;
  41. // -----------------------------------------------------------------------
  42. // Special parameters
  43. enum SpecialParameterType {
  44. PARAMETER_SPECIAL_NULL = 0,
  45. PARAMETER_SPECIAL_FREEWHEEL = 1,
  46. PARAMETER_SPECIAL_LATENCY = 2,
  47. PARAMETER_SPECIAL_SAMPLE_RATE = 3,
  48. PARAMETER_SPECIAL_TIME = 4
  49. };
  50. // -----------------------------------------------------------------------
  51. /*!
  52. * Post-RT event type.
  53. * These are events postponned from within the process function,
  54. *
  55. * During process, we cannot lock, allocate memory or do UI stuff.
  56. * Events have to be postponned to be executed later, on a separate thread.
  57. * @see PluginPostRtEvent
  58. */
  59. enum PluginPostRtEventType {
  60. kPluginPostRtEventNull = 0,
  61. kPluginPostRtEventDebug,
  62. kPluginPostRtEventParameterChange, // param, (unused), (unused), value
  63. kPluginPostRtEventProgramChange, // index
  64. kPluginPostRtEventMidiProgramChange, // index
  65. kPluginPostRtEventNoteOn, // channel, note, velo
  66. kPluginPostRtEventNoteOff // channel, note
  67. };
  68. /*!
  69. * A Post-RT event.
  70. * @see PluginPostRtEventType
  71. */
  72. struct PluginPostRtEvent {
  73. PluginPostRtEventType type;
  74. bool sendCallback;
  75. int32_t value1;
  76. int32_t value2;
  77. int32_t value3;
  78. float valuef;
  79. };
  80. // -----------------------------------------------------------------------
  81. struct ExternalMidiNote {
  82. int8_t channel; // invalid if -1
  83. uint8_t note; // 0 to 127
  84. uint8_t velo; // 1 to 127, 0 for note-off
  85. };
  86. // -----------------------------------------------------------------------
  87. struct PluginAudioPort {
  88. uint32_t rindex;
  89. CarlaEngineAudioPort* port;
  90. };
  91. struct PluginAudioData {
  92. uint32_t count;
  93. PluginAudioPort* ports;
  94. PluginAudioData() noexcept;
  95. ~PluginAudioData() noexcept;
  96. void createNew(uint32_t newCount);
  97. void clear() noexcept;
  98. void initBuffers() const noexcept;
  99. CARLA_DECLARE_NON_COPY_STRUCT(PluginAudioData)
  100. };
  101. // -----------------------------------------------------------------------
  102. struct PluginCVPort {
  103. uint32_t rindex;
  104. //uint32_t param; // FIXME is this needed?
  105. CarlaEngineCVPort* port;
  106. };
  107. struct PluginCVData {
  108. uint32_t count;
  109. PluginCVPort* ports;
  110. PluginCVData() noexcept;
  111. ~PluginCVData() noexcept;
  112. void createNew(uint32_t newCount);
  113. void clear() noexcept;
  114. void initBuffers() const noexcept;
  115. CARLA_DECLARE_NON_COPY_STRUCT(PluginCVData)
  116. };
  117. // -----------------------------------------------------------------------
  118. struct PluginEventData {
  119. CarlaEngineEventPort* portIn;
  120. CarlaEngineEventPort* portOut;
  121. PluginEventData() noexcept;
  122. ~PluginEventData() noexcept;
  123. void clear() noexcept;
  124. void initBuffers() const noexcept;
  125. CARLA_DECLARE_NON_COPY_STRUCT(PluginEventData)
  126. };
  127. // -----------------------------------------------------------------------
  128. struct PluginParameterData {
  129. uint32_t count;
  130. ParameterData* data;
  131. ParameterRanges* ranges;
  132. SpecialParameterType* special;
  133. PluginParameterData() noexcept;
  134. ~PluginParameterData() noexcept;
  135. void createNew(uint32_t newCount, bool withSpecial);
  136. void clear() noexcept;
  137. float getFixedValue(uint32_t parameterId, float value) const noexcept;
  138. CARLA_DECLARE_NON_COPY_STRUCT(PluginParameterData)
  139. };
  140. // -----------------------------------------------------------------------
  141. typedef const char* ProgramName;
  142. struct PluginProgramData {
  143. uint32_t count;
  144. int32_t current;
  145. ProgramName* names;
  146. PluginProgramData() noexcept;
  147. ~PluginProgramData() noexcept;
  148. void createNew(uint32_t newCount);
  149. void clear() noexcept;
  150. CARLA_DECLARE_NON_COPY_STRUCT(PluginProgramData)
  151. };
  152. // -----------------------------------------------------------------------
  153. struct PluginMidiProgramData {
  154. uint32_t count;
  155. int32_t current;
  156. MidiProgramData* data;
  157. PluginMidiProgramData() noexcept;
  158. ~PluginMidiProgramData() noexcept;
  159. void createNew(uint32_t newCount);
  160. void clear() noexcept;
  161. const MidiProgramData& getCurrent() const noexcept;
  162. CARLA_DECLARE_NON_COPY_STRUCT(PluginMidiProgramData)
  163. };
  164. // -----------------------------------------------------------------------
  165. struct CarlaPlugin::ProtectedData {
  166. CarlaEngine* const engine;
  167. CarlaEngineClient* client;
  168. uint id;
  169. uint hints;
  170. uint options;
  171. uint32_t nodeId;
  172. bool active;
  173. bool enabled;
  174. bool needsReset;
  175. bool engineBridged;
  176. bool enginePlugin;
  177. lib_t lib;
  178. lib_t uiLib;
  179. // misc
  180. int8_t ctrlChannel;
  181. uint extraHints;
  182. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  183. uint transientTryCounter;
  184. bool transientFirstTry;
  185. #endif
  186. // data 1
  187. const char* name;
  188. const char* filename;
  189. const char* iconName;
  190. // data 2
  191. PluginAudioData audioIn;
  192. PluginAudioData audioOut;
  193. PluginCVData cvIn;
  194. PluginCVData cvOut;
  195. PluginEventData event;
  196. PluginParameterData param;
  197. PluginProgramData prog;
  198. PluginMidiProgramData midiprog;
  199. LinkedList<CustomData> custom;
  200. CarlaMutex masterMutex; // global master lock
  201. CarlaMutex singleMutex; // small lock used only in processSingle()
  202. CarlaStateSave stateSave;
  203. struct ExternalNotes {
  204. CarlaMutex mutex;
  205. RtLinkedList<ExternalMidiNote>::Pool dataPool;
  206. RtLinkedList<ExternalMidiNote> data;
  207. ExternalNotes() noexcept;
  208. ~ExternalNotes() noexcept;
  209. void appendNonRT(const ExternalMidiNote& note) noexcept;
  210. void clear() noexcept;
  211. CARLA_DECLARE_NON_COPY_STRUCT(ExternalNotes)
  212. } extNotes;
  213. struct Latency {
  214. uint32_t frames;
  215. #ifndef BUILD_BRIDGE
  216. uint32_t channels;
  217. float** buffers;
  218. #endif
  219. Latency() noexcept;
  220. #ifndef BUILD_BRIDGE
  221. ~Latency() noexcept;
  222. void clearBuffers() noexcept;
  223. void recreateBuffers(uint32_t newChannels, uint32_t newFrames);
  224. #endif
  225. CARLA_DECLARE_NON_COPY_STRUCT(Latency)
  226. } latency;
  227. class PostRtEvents {
  228. public:
  229. PostRtEvents() noexcept;
  230. ~PostRtEvents() noexcept;
  231. void appendRT(const PluginPostRtEvent& event) noexcept;
  232. void trySplice() noexcept;
  233. void clearData() noexcept;
  234. inline CarlaMutex& getDataMutex() noexcept
  235. {
  236. return dataMutex;
  237. }
  238. inline RtLinkedList<PluginPostRtEvent>::Itenerator getDataIterator() const noexcept
  239. {
  240. return data.begin2();
  241. }
  242. private:
  243. RtLinkedList<PluginPostRtEvent>::Pool dataPool;
  244. RtLinkedList<PluginPostRtEvent> dataPendingRT;
  245. RtLinkedList<PluginPostRtEvent> data;
  246. CarlaMutex dataMutex;
  247. // TESTING for thread-safety, remove later
  248. CarlaMutex dataPendingMutex;
  249. CARLA_DECLARE_NON_COPY_CLASS(PostRtEvents)
  250. } postRtEvents;
  251. struct PostUiEvents {
  252. CarlaMutex mutex;
  253. LinkedList<PluginPostRtEvent> data;
  254. PostUiEvents() noexcept;
  255. ~PostUiEvents() noexcept;
  256. void append(const PluginPostRtEvent& event) noexcept;
  257. void clear() noexcept;
  258. CARLA_DECLARE_NON_COPY_STRUCT(PostUiEvents)
  259. } postUiEvents;
  260. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  261. struct PostProc {
  262. float dryWet;
  263. float volume;
  264. float balanceLeft;
  265. float balanceRight;
  266. float panning;
  267. PostProc() noexcept;
  268. CARLA_DECLARE_NON_COPY_STRUCT(PostProc)
  269. } postProc;
  270. #endif
  271. ProtectedData(CarlaEngine* engine, uint idx) noexcept;
  272. ~ProtectedData() noexcept;
  273. // -------------------------------------------------------------------
  274. // Buffer functions
  275. void clearBuffers() noexcept;
  276. // -------------------------------------------------------------------
  277. // Post-poned events
  278. void postponeRtEvent(const PluginPostRtEvent& rtEvent) noexcept;
  279. void postponeRtEvent(PluginPostRtEventType type, bool sendCallbackLater,
  280. int32_t value1, int32_t value2, int32_t value3, float valuef) noexcept;
  281. // -------------------------------------------------------------------
  282. // Library functions
  283. static const char* libError(const char* filename) noexcept;
  284. bool libOpen(const char* filename) noexcept;
  285. bool libClose() noexcept;
  286. void setCanDeleteLib(bool canDelete) noexcept;
  287. bool uiLibOpen(const char* filename, bool canDelete) noexcept;
  288. bool uiLibClose() noexcept;
  289. template<typename Func>
  290. Func libSymbol(const char* symbol) const noexcept
  291. {
  292. return lib_symbol<Func>(lib, symbol);
  293. }
  294. template<typename Func>
  295. Func uiLibSymbol(const char* symbol) const noexcept
  296. {
  297. return lib_symbol<Func>(uiLib, symbol);
  298. }
  299. // -------------------------------------------------------------------
  300. // Misc
  301. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  302. void tryTransient() noexcept;
  303. #endif
  304. void updateParameterValues(CarlaPlugin* plugin,
  305. bool sendCallback, bool sendOsc, bool useDefault) noexcept;
  306. void updateDefaultParameterValues(CarlaPlugin* plugin) noexcept;
  307. // -------------------------------------------------------------------
  308. #ifdef CARLA_PROPER_CPP11_SUPPORT
  309. ProtectedData() = delete;
  310. CARLA_DECLARE_NON_COPY_STRUCT(ProtectedData);
  311. #endif
  312. CARLA_LEAK_DETECTOR(ProtectedData);
  313. };
  314. CARLA_BACKEND_END_NAMESPACE
  315. #endif // CARLA_PLUGIN_INTERNAL_HPP_INCLUDED