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.

409 lines
11KB

  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