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.

509 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) 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 group, 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. CarlaCriticalSection connectLock;
  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. void refresh(CarlaEngine* const engine, const LinkedList<PortNameToId>& midiIns, const LinkedList<PortNameToId>& midiOuts) noexcept;
  95. const char* const* getConnections() const;
  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. void refresh(CarlaEngine* const engine, const LinkedList<PortNameToId>& midiIns, const LinkedList<PortNameToId>& midiOuts) noexcept;
  111. const char* const* getConnections() const;
  112. };
  113. #endif
  114. // -----------------------------------------------------------------------
  115. // InternalAudio
  116. struct EngineInternalAudio {
  117. bool isReady;
  118. uint inCount;
  119. uint outCount;
  120. float** inBuf;
  121. float** outBuf;
  122. EngineInternalAudio() noexcept
  123. : isReady(false),
  124. inCount(0),
  125. outCount(0),
  126. inBuf(nullptr),
  127. outBuf(nullptr) {}
  128. ~EngineInternalAudio() noexcept
  129. {
  130. CARLA_SAFE_ASSERT(! isReady);
  131. CARLA_SAFE_ASSERT(inCount == 0);
  132. CARLA_SAFE_ASSERT(outCount == 0);
  133. CARLA_SAFE_ASSERT(inBuf == nullptr);
  134. CARLA_SAFE_ASSERT(outBuf == nullptr);
  135. }
  136. void clearBuffers() noexcept
  137. {
  138. for (uint32_t i=0; i < inCount; ++i)
  139. {
  140. if (inBuf[i] != nullptr)
  141. {
  142. delete[] inBuf[i];
  143. inBuf[i] = nullptr;
  144. }
  145. }
  146. for (uint32_t i=0; i < outCount; ++i)
  147. {
  148. if (outBuf[i] != nullptr)
  149. {
  150. delete[] outBuf[i];
  151. outBuf[i] = nullptr;
  152. }
  153. }
  154. }
  155. void clear() noexcept
  156. {
  157. isReady = false;
  158. clearBuffers();
  159. inCount = 0;
  160. outCount = 0;
  161. if (inBuf != nullptr)
  162. {
  163. delete[] inBuf;
  164. inBuf = nullptr;
  165. }
  166. if (outBuf != nullptr)
  167. {
  168. delete[] outBuf;
  169. outBuf = nullptr;
  170. }
  171. }
  172. void create(const uint32_t bufferSize)
  173. {
  174. CARLA_SAFE_ASSERT(! isReady);
  175. CARLA_SAFE_ASSERT(inBuf == nullptr);
  176. CARLA_SAFE_ASSERT(outBuf == nullptr);
  177. if (inCount > 0)
  178. {
  179. inBuf = new float*[inCount];
  180. for (uint32_t i=0; i < inCount; ++i)
  181. inBuf[i] = nullptr;
  182. }
  183. if (outCount > 0)
  184. {
  185. outBuf = new float*[outCount];
  186. for (uint32_t i=0; i < outCount; ++i)
  187. outBuf[i] = nullptr;
  188. }
  189. resize(bufferSize, false);
  190. isReady = true;
  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. unsigned int hints;
  344. uint32_t bufferSize;
  345. double sampleRate;
  346. bool aboutToClose; // don't re-activate thread if true
  347. unsigned int curPluginCount; // number of plugins loaded (0...max)
  348. unsigned int maxPluginNumber; // number of plugins allowed (0, 16, 99 or 255)
  349. unsigned int 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(float* inBufReal[2], float* outBuf[2], const uint32_t nframes, const bool isOffline);
  375. // extended, will call processRack() in the middle
  376. void processRackFull(float** const inBuf, const uint32_t inCount, float** 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