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.

492 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 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. CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalEvents)
  224. };
  225. #ifndef BUILD_BRIDGE
  226. // -----------------------------------------------------------------------
  227. // InternalGraph
  228. struct EngineInternalGraph {
  229. bool isRack;
  230. union {
  231. RackGraph* rack;
  232. PatchbayGraph* patchbay;
  233. };
  234. EngineInternalGraph() noexcept
  235. : isRack(true)
  236. {
  237. rack = nullptr;
  238. }
  239. ~EngineInternalGraph() noexcept
  240. {
  241. CARLA_SAFE_ASSERT(rack == nullptr);
  242. }
  243. void create()
  244. {
  245. CARLA_SAFE_ASSERT(rack == nullptr);
  246. if (isRack)
  247. rack = new RackGraph();
  248. else
  249. patchbay = new PatchbayGraph();
  250. }
  251. void clear()
  252. {
  253. if (isRack)
  254. {
  255. CARLA_SAFE_ASSERT_RETURN(rack != nullptr,);
  256. delete rack;
  257. rack = nullptr;
  258. }
  259. else
  260. {
  261. CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,);
  262. delete patchbay;
  263. patchbay = nullptr;
  264. }
  265. }
  266. CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalGraph)
  267. };
  268. #endif
  269. // -----------------------------------------------------------------------
  270. // InternalTime
  271. struct EngineInternalTime {
  272. bool playing;
  273. uint64_t frame;
  274. EngineInternalTime() noexcept
  275. : playing(false),
  276. frame(0) {}
  277. CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalTime)
  278. };
  279. // -----------------------------------------------------------------------
  280. // NextAction
  281. enum EnginePostAction {
  282. kEnginePostActionNull,
  283. kEnginePostActionZeroCount,
  284. kEnginePostActionRemovePlugin,
  285. kEnginePostActionSwitchPlugins
  286. };
  287. struct EngineNextAction {
  288. EnginePostAction opcode;
  289. unsigned int pluginId;
  290. unsigned int value;
  291. CarlaMutex mutex;
  292. EngineNextAction() noexcept
  293. : opcode(kEnginePostActionNull),
  294. pluginId(0),
  295. value(0) {}
  296. ~EngineNextAction() noexcept
  297. {
  298. CARLA_SAFE_ASSERT(opcode == kEnginePostActionNull);
  299. }
  300. void ready() const noexcept
  301. {
  302. mutex.lock();
  303. mutex.unlock();
  304. }
  305. CARLA_DECLARE_NON_COPY_STRUCT(EngineNextAction)
  306. };
  307. // -----------------------------------------------------------------------
  308. // EnginePluginData
  309. struct EnginePluginData {
  310. CarlaPlugin* plugin;
  311. float insPeak[2];
  312. float outsPeak[2];
  313. void clear() noexcept
  314. {
  315. plugin = nullptr;
  316. insPeak[0] = insPeak[1] = 0.0f;
  317. outsPeak[0] = outsPeak[1] = 0.0f;
  318. }
  319. };
  320. // -----------------------------------------------------------------------
  321. // CarlaEngineProtectedData
  322. struct CarlaEngineProtectedData {
  323. CarlaEngineOsc osc;
  324. CarlaEngineThread thread;
  325. const CarlaOscData* oscData;
  326. EngineCallbackFunc callback;
  327. void* callbackPtr;
  328. FileCallbackFunc fileCallback;
  329. void* fileCallbackPtr;
  330. unsigned int hints;
  331. uint32_t bufferSize;
  332. double sampleRate;
  333. bool aboutToClose; // don't re-activate thread if true
  334. unsigned int curPluginCount; // number of plugins loaded (0...max)
  335. unsigned int maxPluginNumber; // number of plugins allowed (0, 16, 99 or 255)
  336. unsigned int nextPluginId; // invalid if == maxPluginNumber
  337. CarlaString lastError;
  338. CarlaString name;
  339. EngineOptions options;
  340. EngineTimeInfo timeInfo;
  341. EnginePluginData* plugins;
  342. //#ifndef BUILD_BRIDGE
  343. EngineInternalAudio audio;
  344. //#endif
  345. EngineInternalEvents events;
  346. EngineInternalGraph graph;
  347. EngineInternalTime time;
  348. EngineNextAction nextAction;
  349. // -------------------------------------------------------------------
  350. CarlaEngineProtectedData(CarlaEngine* const engine) noexcept;
  351. ~CarlaEngineProtectedData() noexcept;
  352. // -------------------------------------------------------------------
  353. void doPluginRemove() noexcept;
  354. void doPluginsSwitch() noexcept;
  355. void doNextPluginAction(const bool unlock) noexcept;
  356. #ifndef BUILD_BRIDGE
  357. // -------------------------------------------------------------------
  358. // the base, where plugins run
  359. void processRack(float* inBufReal[2], float* outBuf[2], const uint32_t nframes, const bool isOffline);
  360. // extended, will call processRack() in the middle
  361. void processRackFull(float** const inBuf, const uint32_t inCount, float** const outBuf, const uint32_t outCount, const uint32_t nframes, const bool isOffline);
  362. #endif
  363. // -------------------------------------------------------------------
  364. #ifdef CARLA_PROPER_CPP11_SUPPORT
  365. CarlaEngineProtectedData() = delete;
  366. CARLA_DECLARE_NON_COPY_STRUCT(CarlaEngineProtectedData)
  367. #endif
  368. };
  369. // -----------------------------------------------------------------------
  370. class ScopedActionLock
  371. {
  372. public:
  373. ScopedActionLock(CarlaEngineProtectedData* const data, const EnginePostAction action, const uint pluginId, const uint value, const bool lockWait) noexcept;
  374. ~ScopedActionLock() noexcept;
  375. private:
  376. CarlaEngineProtectedData* const fData;
  377. CARLA_PREVENT_HEAP_ALLOCATION
  378. CARLA_DECLARE_NON_COPY_CLASS(ScopedActionLock)
  379. };
  380. // -----------------------------------------------------------------------
  381. CARLA_BACKEND_END_NAMESPACE
  382. #endif // CARLA_ENGINE_INTERNAL_HPP_INCLUDED