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.

386 lines
11KB

  1. /*
  2. * Carla Plugin
  3. * Copyright (C) 2011-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_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. #include "juce_audio_basics.h"
  27. using juce::FloatVectorOperations;
  28. CARLA_BACKEND_START_NAMESPACE
  29. // -----------------------------------------------------------------------
  30. // Engine helper macro, sets lastError and returns false/NULL
  31. #define CARLA_SAFE_ASSERT_RETURN_ERR(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); pData->engine->setLastError(err); return false; }
  32. #define CARLA_SAFE_ASSERT_RETURN_ERRN(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); pData->engine->setLastError(err); return nullptr; }
  33. #define CARLA_SAFE_EXCEPTION_RETURN_ERR(excptMsg, errMsg) catch(...) { carla_safe_exception(excptMsg, __FILE__, __LINE__); pData->engine->setLastError(errMsg); return false; }
  34. #define CARLA_SAFE_EXCEPTION_RETURN_ERRN(excptMsg, errMsg) catch(...) { carla_safe_exception(excptMsg, __FILE__, __LINE__); pData->engine->setLastError(errMsg); return nullptr; }
  35. // -----------------------------------------------------------------------
  36. // Maximum pre-allocated events for some plugin types
  37. const ushort kPluginMaxMidiEvents = 512;
  38. // -----------------------------------------------------------------------
  39. // Extra plugin hints, hidden from backend
  40. const uint PLUGIN_EXTRA_HINT_HAS_MIDI_IN = 0x01;
  41. const uint PLUGIN_EXTRA_HINT_HAS_MIDI_OUT = 0x02;
  42. const uint PLUGIN_EXTRA_HINT_CAN_RUN_RACK = 0x04;
  43. // -----------------------------------------------------------------------
  44. // Special parameters
  45. enum SpecialParameterType {
  46. PARAMETER_SPECIAL_NULL = 0,
  47. PARAMETER_SPECIAL_FREEWHEEL = 1,
  48. PARAMETER_SPECIAL_LATENCY = 2,
  49. PARAMETER_SPECIAL_SAMPLE_RATE = 3,
  50. PARAMETER_SPECIAL_TIME = 4
  51. };
  52. // -----------------------------------------------------------------------
  53. /*!
  54. * Post-RT event type.
  55. * These are events postponned from within the process function,
  56. *
  57. * During process, we cannot lock, allocate memory or do UI stuff,
  58. * so events have to be postponned to be executed later, on a separate thread.
  59. * @see PluginPostRtEvent
  60. */
  61. enum PluginPostRtEventType {
  62. kPluginPostRtEventNull = 0,
  63. kPluginPostRtEventDebug,
  64. kPluginPostRtEventParameterChange, // param, SP (*), value (SP: if 1 only report change to UI, don't report to Callback and OSC)
  65. kPluginPostRtEventProgramChange, // index
  66. kPluginPostRtEventMidiProgramChange, // index
  67. kPluginPostRtEventNoteOn, // channel, note, velo
  68. kPluginPostRtEventNoteOff // channel, note
  69. };
  70. /*!
  71. * A Post-RT event.
  72. * @see PluginPostRtEventType
  73. */
  74. struct PluginPostRtEvent {
  75. PluginPostRtEventType type;
  76. int32_t value1;
  77. int32_t value2;
  78. float value3;
  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(const 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(const 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(const uint32_t newCount, const bool withSpecial);
  136. void clear() noexcept;
  137. float getFixedValue(const uint32_t parameterId, const 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(const 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(const 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. lib_t lib;
  176. lib_t uiLib;
  177. // misc
  178. int8_t ctrlChannel;
  179. uint extraHints;
  180. uint transientTryCounter;
  181. // data 1
  182. const char* name;
  183. const char* filename;
  184. const char* iconName;
  185. // data 2
  186. PluginAudioData audioIn;
  187. PluginAudioData audioOut;
  188. PluginCVData cvIn;
  189. PluginCVData cvOut;
  190. PluginEventData event;
  191. PluginParameterData param;
  192. PluginProgramData prog;
  193. PluginMidiProgramData midiprog;
  194. LinkedList<CustomData> custom;
  195. CarlaMutex masterMutex; // global master lock
  196. CarlaMutex singleMutex; // small lock used only in processSingle()
  197. CarlaStateSave stateSave;
  198. struct ExternalNotes {
  199. CarlaMutex mutex;
  200. RtLinkedList<ExternalMidiNote>::Pool dataPool;
  201. RtLinkedList<ExternalMidiNote> data;
  202. ExternalNotes() noexcept;
  203. ~ExternalNotes() noexcept;
  204. void appendNonRT(const ExternalMidiNote& note) noexcept;
  205. void clear() noexcept;
  206. CARLA_DECLARE_NON_COPY_STRUCT(ExternalNotes)
  207. } extNotes;
  208. struct Latency {
  209. uint32_t channels;
  210. uint32_t frames;
  211. float** buffers;
  212. Latency() noexcept;
  213. ~Latency() noexcept;
  214. void clearBuffers() noexcept;
  215. void recreateBuffers(const uint32_t newChannels, const uint32_t newFrames);
  216. CARLA_DECLARE_NON_COPY_STRUCT(Latency)
  217. } latency;
  218. struct PostRtEvents {
  219. CarlaMutex mutex;
  220. RtLinkedList<PluginPostRtEvent>::Pool dataPool;
  221. RtLinkedList<PluginPostRtEvent> data;
  222. RtLinkedList<PluginPostRtEvent> dataPendingRT;
  223. PostRtEvents() noexcept;
  224. ~PostRtEvents() noexcept;
  225. void appendRT(const PluginPostRtEvent& event) noexcept;
  226. void trySplice() noexcept;
  227. void clear() noexcept;
  228. CARLA_DECLARE_NON_COPY_STRUCT(PostRtEvents)
  229. } postRtEvents;
  230. struct PostUiEvents {
  231. CarlaMutex mutex;
  232. LinkedList<PluginPostRtEvent> data;
  233. PostUiEvents() noexcept;
  234. ~PostUiEvents() noexcept;
  235. void append(const PluginPostRtEvent& event) noexcept;
  236. void clear() noexcept;
  237. CARLA_DECLARE_NON_COPY_STRUCT(PostUiEvents)
  238. } postUiEvents;
  239. #ifndef BUILD_BRIDGE
  240. struct PostProc {
  241. float dryWet;
  242. float volume;
  243. float balanceLeft;
  244. float balanceRight;
  245. float panning;
  246. PostProc() noexcept;
  247. CARLA_DECLARE_NON_COPY_STRUCT(PostProc)
  248. } postProc;
  249. #endif
  250. ProtectedData(CarlaEngine* const engine, const uint idx) noexcept;
  251. ~ProtectedData() noexcept;
  252. // -------------------------------------------------------------------
  253. // Buffer functions
  254. void clearBuffers() noexcept;
  255. // -------------------------------------------------------------------
  256. // Post-poned events
  257. void postponeRtEvent(const PluginPostRtEvent& rtEvent) noexcept;
  258. void postponeRtEvent(const PluginPostRtEventType type, const int32_t value1, const int32_t value2, const float value3) noexcept;
  259. // -------------------------------------------------------------------
  260. // Library functions
  261. static const char* libError(const char* const filename) noexcept;
  262. bool libOpen(const char* const filename) noexcept;
  263. bool libClose() noexcept;
  264. bool uiLibOpen(const char* const filename, const bool canDelete) noexcept;
  265. bool uiLibClose() noexcept;
  266. template<typename Func>
  267. Func libSymbol(const char* const symbol) const noexcept
  268. {
  269. return lib_symbol<Func>(lib, symbol);
  270. }
  271. template<typename Func>
  272. Func uiLibSymbol(const char* const symbol) const noexcept
  273. {
  274. return lib_symbol<Func>(uiLib, symbol);
  275. }
  276. // -------------------------------------------------------------------
  277. // Misc
  278. #ifndef BUILD_BRIDGE
  279. void tryTransient() noexcept;
  280. #endif
  281. void updateParameterValues(CarlaPlugin* const plugin, const bool sendOsc, const bool sendCallback, const bool useDefault) noexcept;
  282. // -------------------------------------------------------------------
  283. #ifdef CARLA_PROPER_CPP11_SUPPORT
  284. ProtectedData() = delete;
  285. CARLA_DECLARE_NON_COPY_STRUCT(ProtectedData);
  286. #endif
  287. CARLA_LEAK_DETECTOR(ProtectedData);
  288. };
  289. CARLA_BACKEND_END_NAMESPACE
  290. #endif // CARLA_PLUGIN_INTERNAL_HPP_INCLUDED