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.

CarlaEngineInternal.hpp 11KB

11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /*
  2. * Carla Plugin Host
  3. * Copyright (C) 2011-2022 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_ENGINE_INTERNAL_HPP_INCLUDED
  18. #define CARLA_ENGINE_INTERNAL_HPP_INCLUDED
  19. #include "CarlaEngineRunner.hpp"
  20. #include "CarlaEngineUtils.hpp"
  21. #include "CarlaPlugin.hpp"
  22. #include "LinkedList.hpp"
  23. #ifndef BUILD_BRIDGE
  24. # include "CarlaEngineOsc.hpp"
  25. # include "hylia/hylia.h"
  26. #endif
  27. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  28. # include "water/processors/AudioProcessorGraph.h"
  29. # include "water/containers/Array.h"
  30. # include "water/memory/Atomic.h"
  31. #endif
  32. #include <vector>
  33. // FIXME only use CARLA_PREVENT_HEAP_ALLOCATION for structs
  34. // maybe separate macro
  35. typedef struct _jack_position jack_position_t;
  36. struct carla_sem_t;
  37. CARLA_BACKEND_START_NAMESPACE
  38. // -----------------------------------------------------------------------
  39. // Engine helper macro, sets lastError and returns false/NULL
  40. #define CARLA_SAFE_ASSERT_RETURN_ERR(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); setLastError(err); return false; }
  41. #define CARLA_SAFE_ASSERT_RETURN_ERRN(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); setLastError(err); return nullptr; }
  42. #define CARLA_SAFE_EXCEPTION_RETURN_ERR(excptMsg, errMsg) catch(...) { carla_safe_exception(excptMsg, __FILE__, __LINE__); setLastError(errMsg); return false; }
  43. #define CARLA_SAFE_EXCEPTION_RETURN_ERRN(excptMsg, errMsg) catch(...) { carla_safe_exception(excptMsg, __FILE__, __LINE__); setLastError(errMsg); return nullptr; }
  44. // -----------------------------------------------------------------------
  45. // InternalEvents
  46. struct EngineInternalEvents {
  47. EngineEvent* in;
  48. EngineEvent* out;
  49. EngineInternalEvents() noexcept;
  50. ~EngineInternalEvents() noexcept;
  51. void clear() noexcept;
  52. CARLA_DECLARE_NON_COPYABLE(EngineInternalEvents)
  53. };
  54. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  55. // -----------------------------------------------------------------------
  56. // InternalGraph
  57. struct RackGraph;
  58. class PatchbayGraph;
  59. class EngineInternalGraph
  60. {
  61. public:
  62. EngineInternalGraph(CarlaEngine* engine) noexcept;
  63. ~EngineInternalGraph() noexcept;
  64. void create(uint32_t audioIns, uint32_t audioOuts,
  65. uint32_t cvIns, uint32_t cvOuts,
  66. bool withMidiIn = true, bool withMidiOut = true);
  67. void destroy() noexcept;
  68. void setBufferSize(uint32_t bufferSize);
  69. void setSampleRate(double sampleRate);
  70. void setOffline(bool offline);
  71. bool isRack() const noexcept
  72. {
  73. return fIsRack;
  74. }
  75. bool isReady() const noexcept
  76. {
  77. return fIsReady;
  78. }
  79. uint32_t getNumAudioOuts() const noexcept
  80. {
  81. return fNumAudioOuts;
  82. }
  83. RackGraph* getRackGraph() const noexcept;
  84. PatchbayGraph* getPatchbayGraph() const noexcept;
  85. PatchbayGraph* getPatchbayGraphOrNull() const noexcept;
  86. void process(CarlaEngine::ProtectedData* data, const float* const* inBuf, float* const* outBuf, uint32_t frames);
  87. // special direct process with connections already handled, used in JACK and Plugin
  88. void processRack(CarlaEngine::ProtectedData* data, const float* inBuf[2], float* outBuf[2], uint32_t frames);
  89. // used for internal patchbay mode
  90. void addPlugin(CarlaPluginPtr plugin);
  91. void replacePlugin(CarlaPluginPtr oldPlugin, CarlaPluginPtr newPlugin);
  92. void renamePlugin(CarlaPluginPtr plugin, const char* newName);
  93. void switchPlugins(CarlaPluginPtr pluginA, CarlaPluginPtr pluginB);
  94. void removePlugin(CarlaPluginPtr plugin);
  95. void removeAllPlugins(bool aboutToClose);
  96. bool isUsingExternalHost() const noexcept;
  97. bool isUsingExternalOSC() const noexcept;
  98. void setUsingExternalHost(bool usingExternal) noexcept;
  99. void setUsingExternalOSC(bool usingExternal) noexcept;
  100. private:
  101. bool fIsRack;
  102. uint32_t fNumAudioOuts;
  103. volatile bool fIsReady;
  104. union {
  105. RackGraph* fRack;
  106. PatchbayGraph* fPatchbay;
  107. };
  108. CarlaEngine* const kEngine;
  109. CARLA_PREVENT_HEAP_ALLOCATION
  110. CARLA_DECLARE_NON_COPYABLE(EngineInternalGraph)
  111. };
  112. #endif // BUILD_BRIDGE_ALTERNATIVE_ARCH
  113. // -----------------------------------------------------------------------
  114. // InternalTime
  115. class EngineInternalTime {
  116. public:
  117. EngineInternalTime(EngineTimeInfo& timeInfo, const EngineTransportMode& transportMode) noexcept;
  118. void init(uint32_t bufferSize, double sampleRate);
  119. void updateAudioValues(uint32_t bufferSize, double sampleRate);
  120. void enableLink(bool enable);
  121. void setBPM(double bpm);
  122. void setNeedsReset() noexcept;
  123. void pause() noexcept;
  124. void relocate(uint64_t frame) noexcept;
  125. private:
  126. double beatsPerBar;
  127. double beatsPerMinute;
  128. double bufferSize;
  129. double sampleRate;
  130. bool needsReset;
  131. uint64_t nextFrame;
  132. #ifndef BUILD_BRIDGE
  133. struct Hylia {
  134. bool enabled;
  135. hylia_t* instance;
  136. hylia_time_info_t timeInfo;
  137. Hylia();
  138. ~Hylia();
  139. CARLA_DECLARE_NON_COPYABLE(Hylia)
  140. } hylia;
  141. #endif
  142. EngineTimeInfo& timeInfo;
  143. const EngineTransportMode& transportMode;
  144. friend class PendingRtEventsRunner;
  145. void preProcess(uint32_t numFrames);
  146. void fillEngineTimeInfo(uint32_t newFrames) noexcept;
  147. friend class CarlaEngineJack;
  148. void fillJackTimeInfo(jack_position_t* pos, uint32_t newFrames) noexcept;
  149. CARLA_DECLARE_NON_COPYABLE(EngineInternalTime)
  150. };
  151. // -----------------------------------------------------------------------
  152. // EngineNextAction
  153. enum EnginePostAction {
  154. kEnginePostActionNull = 0,
  155. kEnginePostActionZeroCount, // set curPluginCount to 0
  156. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  157. kEnginePostActionRemovePlugin, // remove a plugin
  158. kEnginePostActionSwitchPlugins // switch between 2 plugins
  159. #endif
  160. };
  161. static inline
  162. const char* EnginePostAction2Str(const EnginePostAction action)
  163. {
  164. switch (action)
  165. {
  166. case kEnginePostActionNull:
  167. return "kEnginePostActionNull";
  168. case kEnginePostActionZeroCount:
  169. return "kEnginePostActionZeroCount";
  170. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  171. case kEnginePostActionRemovePlugin:
  172. return "kEnginePostActionRemovePlugin";
  173. case kEnginePostActionSwitchPlugins:
  174. return "kEnginePostActionSwitchPlugins";
  175. #endif
  176. }
  177. carla_stderr("CarlaBackend::EnginePostAction2Str(%i) - invalid action", action);
  178. return nullptr;
  179. }
  180. struct EngineNextAction {
  181. EnginePostAction opcode;
  182. uint pluginId;
  183. uint value;
  184. CarlaMutex mutex;
  185. bool needsPost;
  186. volatile bool postDone;
  187. carla_sem_t* sem;
  188. EngineNextAction() noexcept;
  189. ~EngineNextAction() noexcept;
  190. void clearAndReset() noexcept;
  191. CARLA_DECLARE_NON_COPYABLE(EngineNextAction)
  192. };
  193. // -----------------------------------------------------------------------
  194. // EnginePluginData
  195. struct EnginePluginData {
  196. CarlaPluginPtr plugin;
  197. float peaks[4];
  198. EnginePluginData()
  199. : plugin(nullptr),
  200. #ifdef CARLA_PROPER_CPP11_SUPPORT
  201. peaks{0.0f, 0.0f, 0.0f, 0.0f} {}
  202. #else
  203. peaks()
  204. {
  205. carla_zeroStruct(peaks);
  206. }
  207. #endif
  208. };
  209. // -----------------------------------------------------------------------
  210. // CarlaEngineProtectedData
  211. struct CarlaEngine::ProtectedData {
  212. CarlaEngineRunner runner;
  213. #if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE)
  214. CarlaEngineOsc osc;
  215. #endif
  216. EngineCallbackFunc callback;
  217. void* callbackPtr;
  218. FileCallbackFunc fileCallback;
  219. void* fileCallbackPtr;
  220. bool actionCanceled;
  221. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  222. bool loadingProject;
  223. bool ignoreClientPrefix; // backwards compat only
  224. CarlaString currentProjectFilename;
  225. CarlaString currentProjectFolder;
  226. #endif
  227. uint32_t bufferSize;
  228. double sampleRate;
  229. bool aboutToClose; // don't re-activate runner if true
  230. int isIdling; // don't allow any operations while idling
  231. uint curPluginCount; // number of plugins loaded (0...max)
  232. uint maxPluginNumber; // number of plugins allowed (0, 16, 99 or 255)
  233. uint nextPluginId; // invalid if == maxPluginNumber
  234. CarlaMutex envMutex;
  235. CarlaString lastError;
  236. CarlaString name;
  237. EngineOptions options;
  238. EngineTimeInfo timeInfo;
  239. #ifdef BUILD_BRIDGE_ALTERNATIVE_ARCH
  240. EnginePluginData plugins[1];
  241. #else
  242. EnginePluginData* plugins;
  243. uint32_t xruns;
  244. float dspLoad;
  245. #endif
  246. float peaks[4];
  247. CarlaMutex pluginsToDeleteMutex;
  248. std::vector<CarlaPluginPtr> pluginsToDelete;
  249. EngineInternalEvents events;
  250. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  251. EngineInternalGraph graph;
  252. #endif
  253. EngineInternalTime time;
  254. EngineNextAction nextAction;
  255. // -------------------------------------------------------------------
  256. ProtectedData(CarlaEngine* engine);
  257. ~ProtectedData();
  258. // -------------------------------------------------------------------
  259. bool init(const char* clientName);
  260. void close();
  261. void initTime(const char* features);
  262. // -------------------------------------------------------------------
  263. void deletePluginsAsNeeded();
  264. // -------------------------------------------------------------------
  265. void doPluginRemove(uint pluginId) noexcept;
  266. void doPluginsSwitch(uint idA, uint idB) noexcept;
  267. void doNextPluginAction() noexcept;
  268. // -------------------------------------------------------------------
  269. #ifdef CARLA_PROPER_CPP11_SUPPORT
  270. ProtectedData() = delete;
  271. CARLA_DECLARE_NON_COPYABLE(ProtectedData)
  272. #endif
  273. };
  274. // -----------------------------------------------------------------------
  275. class PendingRtEventsRunner
  276. {
  277. public:
  278. PendingRtEventsRunner(CarlaEngine* engine,
  279. uint32_t numFrames,
  280. bool calcDSPLoad = false) noexcept;
  281. ~PendingRtEventsRunner() noexcept;
  282. private:
  283. CarlaEngine::ProtectedData* const pData;
  284. int64_t prevTime;
  285. CARLA_PREVENT_HEAP_ALLOCATION
  286. CARLA_DECLARE_NON_COPYABLE(PendingRtEventsRunner)
  287. };
  288. // -----------------------------------------------------------------------
  289. class ScopedActionLock
  290. {
  291. public:
  292. ScopedActionLock(CarlaEngine* engine, EnginePostAction action, uint pluginId, uint value) noexcept;
  293. ~ScopedActionLock() noexcept;
  294. private:
  295. CarlaEngine::ProtectedData* const pData;
  296. CARLA_PREVENT_HEAP_ALLOCATION
  297. CARLA_DECLARE_NON_COPYABLE(ScopedActionLock)
  298. };
  299. // -----------------------------------------------------------------------
  300. class ScopedRunnerStopper
  301. {
  302. public:
  303. ScopedRunnerStopper(CarlaEngine* engine) noexcept;
  304. ~ScopedRunnerStopper() noexcept;
  305. private:
  306. CarlaEngine* const engine;
  307. CarlaEngine::ProtectedData* const pData;
  308. CARLA_PREVENT_HEAP_ALLOCATION
  309. CARLA_DECLARE_NON_COPYABLE(ScopedRunnerStopper)
  310. };
  311. // -----------------------------------------------------------------------
  312. CARLA_BACKEND_END_NAMESPACE
  313. #endif // CARLA_ENGINE_INTERNAL_HPP_INCLUDED