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.

CarlaEngineInternal.cpp 11KB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  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. #include "CarlaEngineInternal.hpp"
  18. #include "CarlaPlugin.hpp"
  19. CARLA_BACKEND_START_NAMESPACE
  20. // -----------------------------------------------------------------------
  21. // Engine Internal helper macro, sets lastError and returns false/NULL
  22. #define CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); lastError = err; return false; }
  23. #define CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERRN(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); lastError = err; return nullptr; }
  24. // -----------------------------------------------------------------------
  25. // InternalEvents
  26. EngineInternalEvents::EngineInternalEvents() noexcept
  27. : in(nullptr),
  28. out(nullptr) {}
  29. EngineInternalEvents::~EngineInternalEvents() noexcept
  30. {
  31. CARLA_SAFE_ASSERT(in == nullptr);
  32. CARLA_SAFE_ASSERT(out == nullptr);
  33. }
  34. void EngineInternalEvents::clear() noexcept
  35. {
  36. if (in != nullptr)
  37. {
  38. delete[] in;
  39. in = nullptr;
  40. }
  41. if (out != nullptr)
  42. {
  43. delete[] out;
  44. out = nullptr;
  45. }
  46. }
  47. // -----------------------------------------------------------------------
  48. // InternalTime
  49. EngineInternalTime::EngineInternalTime() noexcept
  50. : playing(false),
  51. frame(0) {}
  52. // -----------------------------------------------------------------------
  53. // NextAction
  54. EngineNextAction::EngineNextAction() noexcept
  55. : opcode(kEnginePostActionNull),
  56. pluginId(0),
  57. value(0),
  58. mutex() {}
  59. EngineNextAction::~EngineNextAction() noexcept
  60. {
  61. CARLA_SAFE_ASSERT(opcode == kEnginePostActionNull);
  62. }
  63. void EngineNextAction::ready() const noexcept
  64. {
  65. mutex.lock();
  66. mutex.unlock();
  67. }
  68. void EngineNextAction::clearAndReset() noexcept
  69. {
  70. mutex.lock();
  71. opcode = kEnginePostActionNull;
  72. pluginId = 0;
  73. value = 0;
  74. mutex.unlock();
  75. }
  76. // -----------------------------------------------------------------------
  77. // CarlaEngine::ProtectedData
  78. CarlaEngine::ProtectedData::ProtectedData(CarlaEngine* const engine) noexcept
  79. : thread(engine),
  80. #ifdef HAVE_LIBLO
  81. osc(engine),
  82. oscData(nullptr),
  83. #endif
  84. callback(nullptr),
  85. callbackPtr(nullptr),
  86. fileCallback(nullptr),
  87. fileCallbackPtr(nullptr),
  88. #ifndef BUILD_BRIDGE
  89. firstLinuxSamplerInstance(true),
  90. loadingProject(false),
  91. #endif
  92. hints(0x0),
  93. bufferSize(0),
  94. sampleRate(0.0),
  95. aboutToClose(false),
  96. isIdling(0),
  97. curPluginCount(0),
  98. maxPluginNumber(0),
  99. nextPluginId(0),
  100. envMutex(),
  101. lastError(),
  102. name(),
  103. options(),
  104. timeInfo(),
  105. #ifndef BUILD_BRIDGE
  106. plugins(nullptr),
  107. #endif
  108. events(),
  109. #ifndef BUILD_BRIDGE
  110. graph(engine),
  111. #endif
  112. time(),
  113. nextAction()
  114. {
  115. #ifdef BUILD_BRIDGE
  116. carla_zeroStructs(plugins, 1);
  117. #endif
  118. }
  119. CarlaEngine::ProtectedData::~ProtectedData() noexcept
  120. {
  121. CARLA_SAFE_ASSERT(curPluginCount == 0);
  122. CARLA_SAFE_ASSERT(maxPluginNumber == 0);
  123. CARLA_SAFE_ASSERT(nextPluginId == 0);
  124. CARLA_SAFE_ASSERT(isIdling == 0);
  125. #ifndef BUILD_BRIDGE
  126. CARLA_SAFE_ASSERT(plugins == nullptr);
  127. #endif
  128. }
  129. // -----------------------------------------------------------------------
  130. bool CarlaEngine::ProtectedData::init(const char* const clientName)
  131. {
  132. CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(name.isEmpty(), "Invalid engine internal data (err #1)");
  133. #ifdef HAVE_LIBLO
  134. CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(oscData == nullptr, "Invalid engine internal data (err #2)");
  135. #endif
  136. CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(events.in == nullptr, "Invalid engine internal data (err #4)");
  137. CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(events.out == nullptr, "Invalid engine internal data (err #5)");
  138. CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(clientName != nullptr && clientName[0] != '\0', "Invalid client name");
  139. #ifndef BUILD_BRIDGE
  140. CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(plugins == nullptr, "Invalid engine internal data (err #3)");
  141. #endif
  142. aboutToClose = false;
  143. curPluginCount = 0;
  144. nextPluginId = 0;
  145. switch (options.processMode)
  146. {
  147. case ENGINE_PROCESS_MODE_CONTINUOUS_RACK:
  148. maxPluginNumber = MAX_RACK_PLUGINS;
  149. options.forceStereo = true; // just in case
  150. break;
  151. case ENGINE_PROCESS_MODE_PATCHBAY:
  152. maxPluginNumber = MAX_PATCHBAY_PLUGINS;
  153. break;
  154. case ENGINE_PROCESS_MODE_BRIDGE:
  155. maxPluginNumber = 1;
  156. break;
  157. default:
  158. maxPluginNumber = MAX_DEFAULT_PLUGINS;
  159. break;
  160. }
  161. switch (options.processMode)
  162. {
  163. case ENGINE_PROCESS_MODE_CONTINUOUS_RACK:
  164. case ENGINE_PROCESS_MODE_PATCHBAY:
  165. case ENGINE_PROCESS_MODE_BRIDGE:
  166. events.in = new EngineEvent[kMaxEngineEventInternalCount];
  167. events.out = new EngineEvent[kMaxEngineEventInternalCount];
  168. break;
  169. default:
  170. break;
  171. }
  172. nextPluginId = maxPluginNumber;
  173. name = clientName;
  174. name.toBasic();
  175. timeInfo.clear();
  176. #ifdef HAVE_LIBLO
  177. osc.init(clientName);
  178. # ifndef BUILD_BRIDGE
  179. oscData = osc.getControlData();
  180. # endif
  181. #endif
  182. #ifndef BUILD_BRIDGE
  183. plugins = new EnginePluginData[maxPluginNumber];
  184. carla_zeroStructs(plugins, maxPluginNumber);
  185. #endif
  186. nextAction.ready();
  187. thread.startThread();
  188. return true;
  189. }
  190. void CarlaEngine::ProtectedData::close()
  191. {
  192. CARLA_SAFE_ASSERT(name.isNotEmpty());
  193. CARLA_SAFE_ASSERT(plugins != nullptr);
  194. CARLA_SAFE_ASSERT(nextPluginId == maxPluginNumber);
  195. CARLA_SAFE_ASSERT(nextAction.opcode == kEnginePostActionNull);
  196. aboutToClose = true;
  197. thread.stopThread(500);
  198. nextAction.ready();
  199. #ifdef HAVE_LIBLO
  200. osc.close();
  201. oscData = nullptr;
  202. #endif
  203. aboutToClose = false;
  204. curPluginCount = 0;
  205. maxPluginNumber = 0;
  206. nextPluginId = 0;
  207. #ifndef BUILD_BRIDGE
  208. if (plugins != nullptr)
  209. {
  210. delete[] plugins;
  211. plugins = nullptr;
  212. }
  213. #endif
  214. events.clear();
  215. name.clear();
  216. }
  217. // -----------------------------------------------------------------------
  218. #ifndef BUILD_BRIDGE
  219. void CarlaEngine::ProtectedData::doPluginRemove() noexcept
  220. {
  221. CARLA_SAFE_ASSERT_RETURN(curPluginCount > 0,);
  222. CARLA_SAFE_ASSERT_RETURN(nextAction.pluginId < curPluginCount,);
  223. --curPluginCount;
  224. // move all plugins 1 spot backwards
  225. for (uint i=nextAction.pluginId; i < curPluginCount; ++i)
  226. {
  227. CarlaPlugin* const plugin(plugins[i+1].plugin);
  228. CARLA_SAFE_ASSERT_BREAK(plugin != nullptr);
  229. plugin->setId(i);
  230. plugins[i].plugin = plugin;
  231. plugins[i].insPeak[0] = 0.0f;
  232. plugins[i].insPeak[1] = 0.0f;
  233. plugins[i].outsPeak[0] = 0.0f;
  234. plugins[i].outsPeak[1] = 0.0f;
  235. }
  236. const uint id(curPluginCount);
  237. // reset last plugin (now removed)
  238. plugins[id].plugin = nullptr;
  239. plugins[id].insPeak[0] = 0.0f;
  240. plugins[id].insPeak[1] = 0.0f;
  241. plugins[id].outsPeak[0] = 0.0f;
  242. plugins[id].outsPeak[1] = 0.0f;
  243. }
  244. void CarlaEngine::ProtectedData::doPluginsSwitch() noexcept
  245. {
  246. CARLA_SAFE_ASSERT_RETURN(curPluginCount >= 2,);
  247. const uint idA(nextAction.pluginId);
  248. const uint idB(nextAction.value);
  249. CARLA_SAFE_ASSERT_RETURN(idA < curPluginCount,);
  250. CARLA_SAFE_ASSERT_RETURN(idB < curPluginCount,);
  251. CARLA_SAFE_ASSERT_RETURN(plugins[idA].plugin != nullptr,);
  252. CARLA_SAFE_ASSERT_RETURN(plugins[idB].plugin != nullptr,);
  253. #if 0
  254. std::swap(plugins[idA].plugin, plugins[idB].plugin);
  255. #else
  256. CarlaPlugin* const tmp(plugins[idA].plugin);
  257. plugins[idA].plugin = plugins[idB].plugin;
  258. plugins[idB].plugin = tmp;
  259. #endif
  260. }
  261. #endif
  262. void CarlaEngine::ProtectedData::doNextPluginAction(const bool unlock) noexcept
  263. {
  264. switch (nextAction.opcode)
  265. {
  266. case kEnginePostActionNull:
  267. break;
  268. case kEnginePostActionZeroCount:
  269. curPluginCount = 0;
  270. break;
  271. #ifndef BUILD_BRIDGE
  272. case kEnginePostActionRemovePlugin:
  273. doPluginRemove();
  274. break;
  275. case kEnginePostActionSwitchPlugins:
  276. doPluginsSwitch();
  277. break;
  278. #endif
  279. }
  280. nextAction.opcode = kEnginePostActionNull;
  281. nextAction.pluginId = 0;
  282. nextAction.value = 0;
  283. if (unlock)
  284. {
  285. nextAction.mutex.tryLock();
  286. nextAction.mutex.unlock();
  287. }
  288. }
  289. // -----------------------------------------------------------------------
  290. // PendingRtEventsRunner
  291. PendingRtEventsRunner::PendingRtEventsRunner(CarlaEngine* const engine) noexcept
  292. : pData(engine->pData) {}
  293. PendingRtEventsRunner::~PendingRtEventsRunner() noexcept
  294. {
  295. pData->doNextPluginAction(true);
  296. if (pData->time.playing)
  297. pData->time.frame += pData->bufferSize;
  298. if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
  299. {
  300. pData->timeInfo.playing = pData->time.playing;
  301. pData->timeInfo.frame = pData->time.frame;
  302. }
  303. }
  304. // -----------------------------------------------------------------------
  305. // ScopedActionLock
  306. ScopedActionLock::ScopedActionLock(CarlaEngine* const engine, const EnginePostAction action, const uint pluginId, const uint value, const bool lockWait) noexcept
  307. : pData(engine->pData)
  308. {
  309. CARLA_SAFE_ASSERT_RETURN(action != kEnginePostActionNull,);
  310. pData->nextAction.mutex.lock();
  311. CARLA_SAFE_ASSERT_RETURN(pData->nextAction.opcode == kEnginePostActionNull,);
  312. pData->nextAction.opcode = action;
  313. pData->nextAction.pluginId = pluginId;
  314. pData->nextAction.value = value;
  315. if (lockWait)
  316. {
  317. // block wait for unlock on processing side
  318. carla_stdout("ScopedPluginAction(%i) - blocking START", pluginId);
  319. pData->nextAction.mutex.lock();
  320. carla_stdout("ScopedPluginAction(%i) - blocking DONE", pluginId);
  321. }
  322. else
  323. {
  324. pData->doNextPluginAction(false);
  325. }
  326. }
  327. ScopedActionLock::~ScopedActionLock() noexcept
  328. {
  329. CARLA_SAFE_ASSERT(pData->nextAction.opcode == kEnginePostActionNull);
  330. pData->nextAction.mutex.tryLock();
  331. pData->nextAction.mutex.unlock();
  332. }
  333. // -----------------------------------------------------------------------
  334. // ScopedThreadStopper
  335. ScopedThreadStopper::ScopedThreadStopper(CarlaEngine* const e) noexcept
  336. : engine(e),
  337. pData(e->pData)
  338. {
  339. pData->thread.stopThread(500);
  340. }
  341. ScopedThreadStopper::~ScopedThreadStopper() noexcept
  342. {
  343. if (engine->isRunning() && ! pData->aboutToClose)
  344. pData->thread.startThread();
  345. }
  346. // -----------------------------------------------------------------------
  347. // ScopedEngineEnvironmentLocker
  348. ScopedEngineEnvironmentLocker::ScopedEngineEnvironmentLocker(CarlaEngine* const engine) noexcept
  349. : pData(engine->pData)
  350. {
  351. pData->envMutex.lock();
  352. }
  353. ScopedEngineEnvironmentLocker::~ScopedEngineEnvironmentLocker() noexcept
  354. {
  355. pData->envMutex.unlock();
  356. }
  357. // -----------------------------------------------------------------------
  358. CARLA_BACKEND_END_NAMESPACE