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.

508 lines
12KB

  1. /*
  2. * Carla Plugin Host
  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_ENGINE_INTERNAL_HPP_INCLUDED
  18. #define CARLA_ENGINE_INTERNAL_HPP_INCLUDED
  19. #include "CarlaEngine.hpp"
  20. #include "CarlaEngineOsc.hpp"
  21. #include "CarlaEngineThread.hpp"
  22. #include "CarlaMathUtils.hpp"
  23. #include "CarlaMutex.hpp"
  24. #include "LinkedList.hpp"
  25. // -----------------------------------------------------------------------
  26. // Engine helper macro, sets lastError and returns false/NULL
  27. #define CARLA_SAFE_ASSERT_RETURN_ERR(cond, err) if (cond) pass(); else { carla_safe_assert(#cond, __FILE__, __LINE__); setLastError(err); return false; }
  28. #define CARLA_SAFE_ASSERT_RETURN_ERRN(cond, err) if (cond) pass(); else { carla_safe_assert(#cond, __FILE__, __LINE__); setLastError(err); return nullptr; }
  29. // -----------------------------------------------------------------------
  30. CARLA_BACKEND_START_NAMESPACE
  31. #if 0
  32. } // Fix editor indentation
  33. #endif
  34. // -----------------------------------------------------------------------
  35. // Maximum pre-allocated events for rack and bridge modes
  36. const unsigned short kMaxEngineEventInternalCount = 512;
  37. #ifndef BUILD_BRIDGE
  38. // -----------------------------------------------------------------------
  39. // Rack Graph stuff
  40. enum RackGraphGroupIds {
  41. RACK_GRAPH_GROUP_CARLA = 0,
  42. RACK_GRAPH_GROUP_AUDIO_IN = 1,
  43. RACK_GRAPH_GROUP_AUDIO_OUT = 2,
  44. RACK_GRAPH_GROUP_MIDI_IN = 3,
  45. RACK_GRAPH_GROUP_MIDI_OUT = 4,
  46. RACK_GRAPH_GROUP_MAX = 5
  47. };
  48. enum RackGraphCarlaPortIds {
  49. RACK_GRAPH_CARLA_PORT_NULL = 0,
  50. RACK_GRAPH_CARLA_PORT_AUDIO_IN1 = 1,
  51. RACK_GRAPH_CARLA_PORT_AUDIO_IN2 = 2,
  52. RACK_GRAPH_CARLA_PORT_AUDIO_OUT1 = 3,
  53. RACK_GRAPH_CARLA_PORT_AUDIO_OUT2 = 4,
  54. RACK_GRAPH_CARLA_PORT_MIDI_IN = 5,
  55. RACK_GRAPH_CARLA_PORT_MIDI_OUT = 6,
  56. RACK_GRAPH_CARLA_PORT_MAX = 7
  57. };
  58. struct PortNameToId {
  59. int port;
  60. char name[STR_MAX+1];
  61. };
  62. struct ConnectionToId {
  63. uint id;
  64. int groupA, portA;
  65. int groupB, portB;
  66. };
  67. // -----------------------------------------------------------------------
  68. // RackGraph
  69. struct RackGraph {
  70. uint lastConnectionId;
  71. CarlaMutex connectLock; // Recursive
  72. LinkedList<int> connectedIn1;
  73. LinkedList<int> connectedIn2;
  74. LinkedList<int> connectedOut1;
  75. LinkedList<int> connectedOut2;
  76. LinkedList<ConnectionToId> usedConnections;
  77. RackGraph() noexcept
  78. : lastConnectionId(0) {}
  79. ~RackGraph() noexcept
  80. {
  81. clear();
  82. }
  83. void clear() noexcept
  84. {
  85. lastConnectionId = 0;
  86. connectedIn1.clear();
  87. connectedIn2.clear();
  88. connectedOut1.clear();
  89. connectedOut2.clear();
  90. usedConnections.clear();
  91. }
  92. bool connect(CarlaEngine* const engine, const int groupA, const int portA, const int groupB, const int portB) noexcept;
  93. bool disconnect(CarlaEngine* const engine, const uint connectionId) noexcept;
  94. const char* const* getConnections() const;
  95. bool getPortIdFromName(const char* const portName, int& groupId, int& portId);
  96. };
  97. // -----------------------------------------------------------------------
  98. // PatchbayGraph
  99. struct PatchbayGraph {
  100. PatchbayGraph() noexcept {}
  101. ~PatchbayGraph()
  102. {
  103. clear();
  104. }
  105. void clear() noexcept
  106. {
  107. }
  108. bool connect(CarlaEngine* const engine, const int groupA, const int portA, const int groupB, const int portB) noexcept;
  109. bool disconnect(CarlaEngine* const engine, const uint connectionId) noexcept;
  110. const char* const* getConnections() const;
  111. bool getPortIdFromName(const char* const portName, int& groupId, int& portId);
  112. };
  113. #endif
  114. // -----------------------------------------------------------------------
  115. // InternalAudio
  116. struct EngineInternalAudio {
  117. bool isReady;
  118. // always 2x2 in rack mode
  119. uint inCount;
  120. uint outCount;
  121. float** inBuf;
  122. float** outBuf;
  123. EngineInternalAudio() noexcept
  124. : isReady(false),
  125. inCount(0),
  126. outCount(0),
  127. inBuf(nullptr),
  128. outBuf(nullptr) {}
  129. ~EngineInternalAudio() noexcept
  130. {
  131. CARLA_SAFE_ASSERT(! isReady);
  132. CARLA_SAFE_ASSERT(inCount == 0);
  133. CARLA_SAFE_ASSERT(outCount == 0);
  134. CARLA_SAFE_ASSERT(inBuf == nullptr);
  135. CARLA_SAFE_ASSERT(outBuf == nullptr);
  136. }
  137. void clearBuffers() noexcept
  138. {
  139. for (uint32_t i=0; i < inCount; ++i)
  140. {
  141. if (inBuf[i] != nullptr)
  142. {
  143. delete[] inBuf[i];
  144. inBuf[i] = nullptr;
  145. }
  146. }
  147. for (uint32_t i=0; i < outCount; ++i)
  148. {
  149. if (outBuf[i] != nullptr)
  150. {
  151. delete[] outBuf[i];
  152. outBuf[i] = nullptr;
  153. }
  154. }
  155. }
  156. void clear() noexcept
  157. {
  158. isReady = false;
  159. clearBuffers();
  160. inCount = 0;
  161. outCount = 0;
  162. if (inBuf != nullptr)
  163. {
  164. delete[] inBuf;
  165. inBuf = nullptr;
  166. }
  167. if (outBuf != nullptr)
  168. {
  169. delete[] outBuf;
  170. outBuf = nullptr;
  171. }
  172. }
  173. void create(const uint32_t bufferSize)
  174. {
  175. CARLA_SAFE_ASSERT(! isReady);
  176. CARLA_SAFE_ASSERT(inBuf == nullptr);
  177. CARLA_SAFE_ASSERT(outBuf == nullptr);
  178. if (inCount > 0)
  179. {
  180. inBuf = new float*[inCount];
  181. for (uint32_t i=0; i < inCount; ++i)
  182. inBuf[i] = nullptr;
  183. }
  184. if (outCount > 0)
  185. {
  186. outBuf = new float*[outCount];
  187. for (uint32_t i=0; i < outCount; ++i)
  188. outBuf[i] = nullptr;
  189. }
  190. resize(bufferSize, false);
  191. }
  192. void resize(const uint32_t bufferSize, const bool doClear = true)
  193. {
  194. if (doClear)
  195. clearBuffers();
  196. CARLA_SAFE_ASSERT_RETURN(bufferSize != 0,);
  197. for (uint32_t i=0; i < inCount; ++i)
  198. {
  199. inBuf[i] = new float[bufferSize];
  200. FLOAT_CLEAR(inBuf[i], bufferSize);
  201. }
  202. for (uint32_t i=0; i < outCount; ++i)
  203. {
  204. outBuf[i] = new float[bufferSize];
  205. FLOAT_CLEAR(outBuf[i], bufferSize);
  206. }
  207. }
  208. CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalAudio)
  209. };
  210. // -----------------------------------------------------------------------
  211. // InternalEvents
  212. struct EngineInternalEvents {
  213. EngineEvent* in;
  214. EngineEvent* out;
  215. EngineInternalEvents() noexcept
  216. : in(nullptr),
  217. out(nullptr) {}
  218. ~EngineInternalEvents() noexcept
  219. {
  220. CARLA_SAFE_ASSERT(in == nullptr);
  221. CARLA_SAFE_ASSERT(out == nullptr);
  222. }
  223. void clear() noexcept
  224. {
  225. if (in != nullptr)
  226. {
  227. delete[] in;
  228. in = nullptr;
  229. }
  230. if (out != nullptr)
  231. {
  232. delete[] out;
  233. out = nullptr;
  234. }
  235. }
  236. CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalEvents)
  237. };
  238. #ifndef BUILD_BRIDGE
  239. // -----------------------------------------------------------------------
  240. // InternalGraph
  241. struct EngineInternalGraph {
  242. bool isRack;
  243. union {
  244. RackGraph* rack;
  245. PatchbayGraph* patchbay;
  246. };
  247. EngineInternalGraph() noexcept
  248. : isRack(true)
  249. {
  250. rack = nullptr;
  251. }
  252. ~EngineInternalGraph() noexcept
  253. {
  254. CARLA_SAFE_ASSERT(rack == nullptr);
  255. }
  256. void create()
  257. {
  258. CARLA_SAFE_ASSERT(rack == nullptr);
  259. if (isRack)
  260. rack = new RackGraph();
  261. else
  262. patchbay = new PatchbayGraph();
  263. }
  264. void clear()
  265. {
  266. if (isRack)
  267. {
  268. CARLA_SAFE_ASSERT_RETURN(rack != nullptr,);
  269. delete rack;
  270. rack = nullptr;
  271. }
  272. else
  273. {
  274. CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,);
  275. delete patchbay;
  276. patchbay = nullptr;
  277. }
  278. }
  279. CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalGraph)
  280. };
  281. #endif
  282. // -----------------------------------------------------------------------
  283. // InternalTime
  284. struct EngineInternalTime {
  285. bool playing;
  286. uint64_t frame;
  287. EngineInternalTime() noexcept
  288. : playing(false),
  289. frame(0) {}
  290. CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalTime)
  291. };
  292. // -----------------------------------------------------------------------
  293. // NextAction
  294. enum EnginePostAction {
  295. kEnginePostActionNull,
  296. kEnginePostActionZeroCount,
  297. kEnginePostActionRemovePlugin,
  298. kEnginePostActionSwitchPlugins
  299. };
  300. struct EngineNextAction {
  301. EnginePostAction opcode;
  302. unsigned int pluginId;
  303. unsigned int value;
  304. CarlaMutex mutex;
  305. EngineNextAction() noexcept
  306. : opcode(kEnginePostActionNull),
  307. pluginId(0),
  308. value(0) {}
  309. ~EngineNextAction() noexcept
  310. {
  311. CARLA_SAFE_ASSERT(opcode == kEnginePostActionNull);
  312. }
  313. void ready() const noexcept
  314. {
  315. mutex.lock();
  316. mutex.unlock();
  317. }
  318. CARLA_DECLARE_NON_COPY_STRUCT(EngineNextAction)
  319. };
  320. // -----------------------------------------------------------------------
  321. // EnginePluginData
  322. struct EnginePluginData {
  323. CarlaPlugin* plugin;
  324. float insPeak[2];
  325. float outsPeak[2];
  326. void clear() noexcept
  327. {
  328. plugin = nullptr;
  329. insPeak[0] = insPeak[1] = 0.0f;
  330. outsPeak[0] = outsPeak[1] = 0.0f;
  331. }
  332. };
  333. // -----------------------------------------------------------------------
  334. // CarlaEngineProtectedData
  335. struct CarlaEngineProtectedData {
  336. CarlaEngineOsc osc;
  337. CarlaEngineThread thread;
  338. const CarlaOscData* oscData;
  339. EngineCallbackFunc callback;
  340. void* callbackPtr;
  341. FileCallbackFunc fileCallback;
  342. void* fileCallbackPtr;
  343. uint hints;
  344. uint32_t bufferSize;
  345. double sampleRate;
  346. bool aboutToClose; // don't re-activate thread if true
  347. uint curPluginCount; // number of plugins loaded (0...max)
  348. uint maxPluginNumber; // number of plugins allowed (0, 16, 99 or 255)
  349. uint nextPluginId; // invalid if == maxPluginNumber
  350. CarlaString lastError;
  351. CarlaString name;
  352. EngineOptions options;
  353. EngineTimeInfo timeInfo;
  354. EnginePluginData* plugins;
  355. #ifndef BUILD_BRIDGE
  356. EngineInternalAudio audio;
  357. #endif
  358. EngineInternalEvents events;
  359. #ifndef BUILD_BRIDGE
  360. EngineInternalGraph graph;
  361. #endif
  362. EngineInternalTime time;
  363. EngineNextAction nextAction;
  364. // -------------------------------------------------------------------
  365. CarlaEngineProtectedData(CarlaEngine* const engine) noexcept;
  366. ~CarlaEngineProtectedData() noexcept;
  367. // -------------------------------------------------------------------
  368. void doPluginRemove() noexcept;
  369. void doPluginsSwitch() noexcept;
  370. void doNextPluginAction(const bool unlock) noexcept;
  371. #ifndef BUILD_BRIDGE
  372. // -------------------------------------------------------------------
  373. // the base, where plugins run
  374. void processRack(const float* inBufReal[2], float* outBuf[2], const uint32_t nframes, const bool isOffline);
  375. // extended, will call processRack() in the middle
  376. void processRackFull(const float* const* const inBuf, const uint32_t inCount, float* const* const outBuf, const uint32_t outCount, const uint32_t nframes, const bool isOffline);
  377. #endif
  378. // -------------------------------------------------------------------
  379. #ifdef CARLA_PROPER_CPP11_SUPPORT
  380. CarlaEngineProtectedData() = delete;
  381. CARLA_DECLARE_NON_COPY_STRUCT(CarlaEngineProtectedData)
  382. #endif
  383. };
  384. // -----------------------------------------------------------------------
  385. class ScopedActionLock
  386. {
  387. public:
  388. ScopedActionLock(CarlaEngineProtectedData* const data, const EnginePostAction action, const uint pluginId, const uint value, const bool lockWait) noexcept;
  389. ~ScopedActionLock() noexcept;
  390. private:
  391. CarlaEngineProtectedData* const fData;
  392. CARLA_PREVENT_HEAP_ALLOCATION
  393. CARLA_DECLARE_NON_COPY_CLASS(ScopedActionLock)
  394. };
  395. // -----------------------------------------------------------------------
  396. CARLA_BACKEND_END_NAMESPACE
  397. #endif // CARLA_ENGINE_INTERNAL_HPP_INCLUDED