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.

407 lines
11KB

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