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.

537 lines
13KB

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