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.

495 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. #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. static const float kTicksPerBeat = 1920.0f;
  50. EngineInternalTime::EngineInternalTime() noexcept
  51. : playing(false),
  52. frame(0),
  53. bpm(120.0),
  54. sampleRate(0.0),
  55. tick(0.0) {}
  56. void EngineInternalTime::fillEngineTimeInfo(EngineTimeInfo& info, const uint32_t newFrames) noexcept
  57. {
  58. CARLA_SAFE_ASSERT_RETURN(carla_isNotZero(sampleRate),);
  59. info.playing = playing;
  60. info.frame = frame;
  61. info.usecs = 0;
  62. if (newFrames == 0)
  63. {
  64. info.valid = EngineTimeInfo::kValidBBT;
  65. info.bbt.beatsPerBar = 4.0f;
  66. info.bbt.beatType = 4.0f;
  67. info.bbt.ticksPerBeat = kTicksPerBeat;
  68. info.bbt.beatsPerMinute = bpm;
  69. double abs_beat, abs_tick;
  70. {
  71. const double min = frame / (sampleRate * 60.0);
  72. abs_tick = min * bpm * kTicksPerBeat;
  73. abs_beat = abs_tick / kTicksPerBeat;
  74. }
  75. info.bbt.bar = abs_beat / info.bbt.beatsPerBar;
  76. info.bbt.beat = abs_beat - (info.bbt.bar * info.bbt.beatsPerBar) + 1;
  77. tick = abs_tick - (abs_beat * kTicksPerBeat);
  78. info.bbt.barStartTick = info.bbt.bar * info.bbt.beatsPerBar * kTicksPerBeat;
  79. info.bbt.bar++;
  80. }
  81. else
  82. {
  83. tick += newFrames * kTicksPerBeat * bpm / (sampleRate * 60);
  84. while (tick >= kTicksPerBeat)
  85. {
  86. tick -= kTicksPerBeat;
  87. if (++info.bbt.beat > info.bbt.beatsPerBar)
  88. {
  89. info.bbt.beat = 1;
  90. ++info.bbt.bar;
  91. info.bbt.barStartTick += info.bbt.beatsPerBar * kTicksPerBeat;
  92. }
  93. }
  94. }
  95. info.bbt.tick = (int)(tick + 0.5);
  96. }
  97. // -----------------------------------------------------------------------
  98. // NextAction
  99. EngineNextAction::EngineNextAction() noexcept
  100. : opcode(kEnginePostActionNull),
  101. pluginId(0),
  102. value(0),
  103. mutex(false) {}
  104. EngineNextAction::~EngineNextAction() noexcept
  105. {
  106. CARLA_SAFE_ASSERT(opcode == kEnginePostActionNull);
  107. }
  108. void EngineNextAction::ready() const noexcept
  109. {
  110. mutex.lock();
  111. mutex.unlock();
  112. }
  113. void EngineNextAction::clearAndReset() noexcept
  114. {
  115. mutex.lock();
  116. opcode = kEnginePostActionNull;
  117. pluginId = 0;
  118. value = 0;
  119. mutex.unlock();
  120. }
  121. // -----------------------------------------------------------------------
  122. // CarlaEngine::ProtectedData
  123. CarlaEngine::ProtectedData::ProtectedData(CarlaEngine* const engine) noexcept
  124. : thread(engine),
  125. #ifdef HAVE_LIBLO
  126. osc(engine),
  127. oscData(nullptr),
  128. #endif
  129. callback(nullptr),
  130. callbackPtr(nullptr),
  131. fileCallback(nullptr),
  132. fileCallbackPtr(nullptr),
  133. #ifndef BUILD_BRIDGE
  134. firstLinuxSamplerInstance(true),
  135. loadingProject(false),
  136. #endif
  137. hints(0x0),
  138. bufferSize(0),
  139. sampleRate(0.0),
  140. aboutToClose(false),
  141. isIdling(0),
  142. curPluginCount(0),
  143. maxPluginNumber(0),
  144. nextPluginId(0),
  145. envMutex(),
  146. lastError(),
  147. name(),
  148. options(),
  149. timeInfo(),
  150. #ifndef BUILD_BRIDGE
  151. plugins(nullptr),
  152. #endif
  153. events(),
  154. #ifndef BUILD_BRIDGE
  155. graph(engine),
  156. #endif
  157. time(),
  158. nextAction()
  159. {
  160. #ifdef BUILD_BRIDGE
  161. carla_zeroStructs(plugins, 1);
  162. #endif
  163. }
  164. CarlaEngine::ProtectedData::~ProtectedData() noexcept
  165. {
  166. CARLA_SAFE_ASSERT(curPluginCount == 0);
  167. CARLA_SAFE_ASSERT(maxPluginNumber == 0);
  168. CARLA_SAFE_ASSERT(nextPluginId == 0);
  169. CARLA_SAFE_ASSERT(isIdling == 0);
  170. #ifndef BUILD_BRIDGE
  171. CARLA_SAFE_ASSERT(plugins == nullptr);
  172. #endif
  173. }
  174. // -----------------------------------------------------------------------
  175. bool CarlaEngine::ProtectedData::init(const char* const clientName)
  176. {
  177. CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(name.isEmpty(), "Invalid engine internal data (err #1)");
  178. #ifdef HAVE_LIBLO
  179. CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(oscData == nullptr, "Invalid engine internal data (err #2)");
  180. #endif
  181. CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(events.in == nullptr, "Invalid engine internal data (err #4)");
  182. CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(events.out == nullptr, "Invalid engine internal data (err #5)");
  183. CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(clientName != nullptr && clientName[0] != '\0', "Invalid client name");
  184. #ifndef BUILD_BRIDGE
  185. CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(plugins == nullptr, "Invalid engine internal data (err #3)");
  186. #endif
  187. aboutToClose = false;
  188. curPluginCount = 0;
  189. nextPluginId = 0;
  190. switch (options.processMode)
  191. {
  192. case ENGINE_PROCESS_MODE_CONTINUOUS_RACK:
  193. maxPluginNumber = MAX_RACK_PLUGINS;
  194. options.forceStereo = true;
  195. break;
  196. case ENGINE_PROCESS_MODE_PATCHBAY:
  197. maxPluginNumber = MAX_PATCHBAY_PLUGINS;
  198. break;
  199. case ENGINE_PROCESS_MODE_BRIDGE:
  200. maxPluginNumber = 1;
  201. break;
  202. default:
  203. maxPluginNumber = MAX_DEFAULT_PLUGINS;
  204. break;
  205. }
  206. switch (options.processMode)
  207. {
  208. case ENGINE_PROCESS_MODE_CONTINUOUS_RACK:
  209. case ENGINE_PROCESS_MODE_PATCHBAY:
  210. case ENGINE_PROCESS_MODE_BRIDGE:
  211. events.in = new EngineEvent[kMaxEngineEventInternalCount];
  212. events.out = new EngineEvent[kMaxEngineEventInternalCount];
  213. break;
  214. default:
  215. break;
  216. }
  217. nextPluginId = maxPluginNumber;
  218. name = clientName;
  219. name.toBasic();
  220. timeInfo.clear();
  221. #ifdef HAVE_LIBLO
  222. osc.init(clientName);
  223. # ifndef BUILD_BRIDGE
  224. oscData = osc.getControlData();
  225. # endif
  226. #endif
  227. #ifndef BUILD_BRIDGE
  228. plugins = new EnginePluginData[maxPluginNumber];
  229. carla_zeroStructs(plugins, maxPluginNumber);
  230. #endif
  231. nextAction.ready();
  232. thread.startThread();
  233. return true;
  234. }
  235. void CarlaEngine::ProtectedData::close()
  236. {
  237. CARLA_SAFE_ASSERT(name.isNotEmpty());
  238. CARLA_SAFE_ASSERT(plugins != nullptr);
  239. CARLA_SAFE_ASSERT(nextPluginId == maxPluginNumber);
  240. CARLA_SAFE_ASSERT(nextAction.opcode == kEnginePostActionNull);
  241. aboutToClose = true;
  242. thread.stopThread(500);
  243. nextAction.ready();
  244. #ifdef HAVE_LIBLO
  245. osc.close();
  246. oscData = nullptr;
  247. #endif
  248. aboutToClose = false;
  249. curPluginCount = 0;
  250. maxPluginNumber = 0;
  251. nextPluginId = 0;
  252. #ifndef BUILD_BRIDGE
  253. if (plugins != nullptr)
  254. {
  255. delete[] plugins;
  256. plugins = nullptr;
  257. }
  258. #endif
  259. events.clear();
  260. name.clear();
  261. }
  262. void CarlaEngine::ProtectedData::initTime()
  263. {
  264. time.playing = false;
  265. time.frame = 0;
  266. time.bpm = 120.0;
  267. time.sampleRate = sampleRate;
  268. time.tick = 0.0;
  269. time.fillEngineTimeInfo(timeInfo, 0);
  270. }
  271. // -----------------------------------------------------------------------
  272. #ifndef BUILD_BRIDGE
  273. void CarlaEngine::ProtectedData::doPluginRemove() noexcept
  274. {
  275. CARLA_SAFE_ASSERT_RETURN(curPluginCount > 0,);
  276. CARLA_SAFE_ASSERT_RETURN(nextAction.pluginId < curPluginCount,);
  277. --curPluginCount;
  278. // move all plugins 1 spot backwards
  279. for (uint i=nextAction.pluginId; i < curPluginCount; ++i)
  280. {
  281. CarlaPlugin* const plugin(plugins[i+1].plugin);
  282. CARLA_SAFE_ASSERT_BREAK(plugin != nullptr);
  283. plugin->setId(i);
  284. plugins[i].plugin = plugin;
  285. plugins[i].insPeak[0] = 0.0f;
  286. plugins[i].insPeak[1] = 0.0f;
  287. plugins[i].outsPeak[0] = 0.0f;
  288. plugins[i].outsPeak[1] = 0.0f;
  289. }
  290. const uint id(curPluginCount);
  291. // reset last plugin (now removed)
  292. plugins[id].plugin = nullptr;
  293. plugins[id].insPeak[0] = 0.0f;
  294. plugins[id].insPeak[1] = 0.0f;
  295. plugins[id].outsPeak[0] = 0.0f;
  296. plugins[id].outsPeak[1] = 0.0f;
  297. }
  298. void CarlaEngine::ProtectedData::doPluginsSwitch() noexcept
  299. {
  300. CARLA_SAFE_ASSERT_RETURN(curPluginCount >= 2,);
  301. const uint idA(nextAction.pluginId);
  302. const uint idB(nextAction.value);
  303. CARLA_SAFE_ASSERT_RETURN(idA < curPluginCount,);
  304. CARLA_SAFE_ASSERT_RETURN(idB < curPluginCount,);
  305. CARLA_SAFE_ASSERT_RETURN(plugins[idA].plugin != nullptr,);
  306. CARLA_SAFE_ASSERT_RETURN(plugins[idB].plugin != nullptr,);
  307. #if 0
  308. std::swap(plugins[idA].plugin, plugins[idB].plugin);
  309. #else
  310. CarlaPlugin* const tmp(plugins[idA].plugin);
  311. plugins[idA].plugin = plugins[idB].plugin;
  312. plugins[idB].plugin = tmp;
  313. #endif
  314. }
  315. #endif
  316. void CarlaEngine::ProtectedData::doNextPluginAction(const bool unlock) noexcept
  317. {
  318. switch (nextAction.opcode)
  319. {
  320. case kEnginePostActionNull:
  321. break;
  322. case kEnginePostActionZeroCount:
  323. curPluginCount = 0;
  324. break;
  325. #ifndef BUILD_BRIDGE
  326. case kEnginePostActionRemovePlugin:
  327. doPluginRemove();
  328. break;
  329. case kEnginePostActionSwitchPlugins:
  330. doPluginsSwitch();
  331. break;
  332. #endif
  333. }
  334. nextAction.opcode = kEnginePostActionNull;
  335. nextAction.pluginId = 0;
  336. nextAction.value = 0;
  337. if (unlock)
  338. {
  339. nextAction.mutex.tryLock();
  340. nextAction.mutex.unlock();
  341. }
  342. }
  343. // -----------------------------------------------------------------------
  344. // PendingRtEventsRunner
  345. PendingRtEventsRunner::PendingRtEventsRunner(CarlaEngine* const engine) noexcept
  346. : pData(engine->pData) {}
  347. PendingRtEventsRunner::~PendingRtEventsRunner() noexcept
  348. {
  349. pData->doNextPluginAction(true);
  350. if (pData->time.playing && pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
  351. {
  352. pData->time.frame += pData->bufferSize;
  353. pData->time.fillEngineTimeInfo(pData->timeInfo, pData->bufferSize);
  354. }
  355. }
  356. // -----------------------------------------------------------------------
  357. // ScopedActionLock
  358. ScopedActionLock::ScopedActionLock(CarlaEngine* const engine, const EnginePostAction action, const uint pluginId, const uint value, const bool lockWait) noexcept
  359. : pData(engine->pData)
  360. {
  361. CARLA_SAFE_ASSERT_RETURN(action != kEnginePostActionNull,);
  362. pData->nextAction.mutex.lock();
  363. CARLA_SAFE_ASSERT_RETURN(pData->nextAction.opcode == kEnginePostActionNull,);
  364. pData->nextAction.opcode = action;
  365. pData->nextAction.pluginId = pluginId;
  366. pData->nextAction.value = value;
  367. if (lockWait)
  368. {
  369. // block wait for unlock on processing side
  370. carla_stdout("ScopedPluginAction(%i) - blocking START", pluginId);
  371. pData->nextAction.mutex.lock();
  372. carla_stdout("ScopedPluginAction(%i) - blocking DONE", pluginId);
  373. }
  374. else
  375. {
  376. pData->doNextPluginAction(false);
  377. }
  378. }
  379. ScopedActionLock::~ScopedActionLock() noexcept
  380. {
  381. CARLA_SAFE_ASSERT(pData->nextAction.opcode == kEnginePostActionNull);
  382. pData->nextAction.mutex.tryLock();
  383. pData->nextAction.mutex.unlock();
  384. }
  385. // -----------------------------------------------------------------------
  386. // ScopedThreadStopper
  387. ScopedThreadStopper::ScopedThreadStopper(CarlaEngine* const e) noexcept
  388. : engine(e),
  389. pData(e->pData)
  390. {
  391. pData->thread.stopThread(500);
  392. }
  393. ScopedThreadStopper::~ScopedThreadStopper() noexcept
  394. {
  395. if (engine->isRunning() && ! pData->aboutToClose)
  396. pData->thread.startThread();
  397. }
  398. // -----------------------------------------------------------------------
  399. // ScopedEngineEnvironmentLocker
  400. ScopedEngineEnvironmentLocker::ScopedEngineEnvironmentLocker(CarlaEngine* const engine) noexcept
  401. : pData(engine->pData)
  402. {
  403. pData->envMutex.lock();
  404. }
  405. ScopedEngineEnvironmentLocker::~ScopedEngineEnvironmentLocker() noexcept
  406. {
  407. pData->envMutex.unlock();
  408. }
  409. // -----------------------------------------------------------------------
  410. CARLA_BACKEND_END_NAMESPACE