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.

433 lines
11KB

  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