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.

1084 lines
28KB

  1. /*
  2. * DISTRHO Cardinal Plugin
  3. * Copyright (C) 2021 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 3 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 LICENSE file.
  16. */
  17. /**
  18. * This file is an edited version of VCVRack's Engine.cpp
  19. * Copyright (C) 2016-2021 VCV.
  20. *
  21. * This program is free software: you can redistribute it and/or
  22. * modify it under the terms of the GNU General Public License as
  23. * published by the Free Software Foundation; either version 3 of
  24. * the License, or (at your option) any later version.
  25. */
  26. #include <algorithm>
  27. #include <set>
  28. #include <thread>
  29. #include <condition_variable>
  30. #include <mutex>
  31. #include <atomic>
  32. #include <tuple>
  33. #include <pmmintrin.h>
  34. #include <pthread.h>
  35. #include <engine/Engine.hpp>
  36. #include <settings.hpp>
  37. #include <system.hpp>
  38. #include <random.hpp>
  39. #include <patch.hpp>
  40. #include <plugin.hpp>
  41. #include <helpers.hpp>
  42. #ifdef NDEBUG
  43. # undef DEBUG
  44. #endif
  45. #include "DistrhoUtils.hpp"
  46. namespace rack {
  47. namespace engine {
  48. /** Allows multiple "reader" threads to obtain a lock simultaneously, but only one "writer" thread.
  49. This implementation is currently just a wrapper for pthreads, which works on Linux/Mac/.
  50. This is available in C++17 as std::shared_mutex, but unfortunately we're using C++11.
  51. */
  52. struct ReadWriteMutex {
  53. pthread_rwlock_t rwlock;
  54. ReadWriteMutex() {
  55. if (pthread_rwlock_init(&rwlock, nullptr))
  56. throw Exception("pthread_rwlock_init failed");
  57. }
  58. ~ReadWriteMutex() {
  59. pthread_rwlock_destroy(&rwlock);
  60. }
  61. void lockReader() {
  62. DISTRHO_SAFE_ASSERT_RETURN(pthread_rwlock_rdlock(&rwlock) == 0,);
  63. }
  64. void unlockReader() {
  65. DISTRHO_SAFE_ASSERT_RETURN(pthread_rwlock_unlock(&rwlock) == 0,);
  66. }
  67. void lockWriter() {
  68. DISTRHO_SAFE_ASSERT_RETURN(pthread_rwlock_wrlock(&rwlock) == 0,);
  69. }
  70. void unlockWriter() {
  71. DISTRHO_SAFE_ASSERT_RETURN(pthread_rwlock_unlock(&rwlock) == 0,);
  72. }
  73. };
  74. struct ReadLock {
  75. ReadWriteMutex& m;
  76. ReadLock(ReadWriteMutex& m) : m(m) {
  77. m.lockReader();
  78. }
  79. ~ReadLock() {
  80. m.unlockReader();
  81. }
  82. };
  83. struct WriteLock {
  84. ReadWriteMutex& m;
  85. WriteLock(ReadWriteMutex& m) : m(m) {
  86. m.lockWriter();
  87. }
  88. ~WriteLock() {
  89. m.unlockWriter();
  90. }
  91. };
  92. struct Engine::Internal {
  93. std::vector<Module*> modules;
  94. std::vector<Cable*> cables;
  95. std::set<ParamHandle*> paramHandles;
  96. // moduleId
  97. std::map<int64_t, Module*> modulesCache;
  98. // cableId
  99. std::map<int64_t, Cable*> cablesCache;
  100. // (moduleId, paramId)
  101. std::map<std::tuple<int64_t, int>, ParamHandle*> paramHandlesCache;
  102. float sampleRate = 0.f;
  103. float sampleTime = 0.f;
  104. int64_t block = 0;
  105. int64_t frame = 0;
  106. int64_t blockFrame = 0;
  107. double blockTime = 0.0;
  108. int blockFrames = 0;
  109. // Meter
  110. int meterCount = 0;
  111. double meterTotal = 0.0;
  112. double meterMax = 0.0;
  113. double meterLastTime = -INFINITY;
  114. double meterLastAverage = 0.0;
  115. double meterLastMax = 0.0;
  116. // Parameter smoothing
  117. Module* smoothModule = NULL;
  118. int smoothParamId = 0;
  119. float smoothValue = 0.f;
  120. /** Mutex that guards the Engine state, such as settings, Modules, and Cables.
  121. Writers lock when mutating the engine's state or stepping the block.
  122. Readers lock when using the engine's state.
  123. */
  124. ReadWriteMutex mutex;
  125. };
  126. static void Engine_updateExpander_NoLock(Engine* that, Module* module, bool side) {
  127. Module::Expander& expander = side ? module->rightExpander : module->leftExpander;
  128. Module* oldExpanderModule = expander.module;
  129. if (expander.moduleId >= 0) {
  130. if (!expander.module || expander.module->id != expander.moduleId) {
  131. expander.module = that->getModule_NoLock(expander.moduleId);
  132. }
  133. }
  134. else {
  135. if (expander.module) {
  136. expander.module = NULL;
  137. }
  138. }
  139. if (expander.module != oldExpanderModule) {
  140. // Dispatch ExpanderChangeEvent
  141. Module::ExpanderChangeEvent e;
  142. e.side = side;
  143. module->onExpanderChange(e);
  144. }
  145. }
  146. static void Cable_step(Cable* that) {
  147. Output* output = &that->outputModule->outputs[that->outputId];
  148. Input* input = &that->inputModule->inputs[that->inputId];
  149. // Match number of polyphonic channels to output port
  150. int channels = output->channels;
  151. // Copy all voltages from output to input
  152. for (int c = 0; c < channels; c++) {
  153. float v = output->voltages[c];
  154. // Set 0V if infinite or NaN
  155. if (!std::isfinite(v))
  156. v = 0.f;
  157. input->voltages[c] = v;
  158. }
  159. // Set higher channel voltages to 0
  160. for (int c = channels; c < input->channels; c++) {
  161. input->voltages[c] = 0.f;
  162. }
  163. input->channels = channels;
  164. }
  165. /** Steps a single frame
  166. */
  167. static void Engine_stepFrame(Engine* that) {
  168. Engine::Internal* internal = that->internal;
  169. // Param smoothing
  170. Module* smoothModule = internal->smoothModule;
  171. if (smoothModule) {
  172. int smoothParamId = internal->smoothParamId;
  173. float smoothValue = internal->smoothValue;
  174. Param* smoothParam = &smoothModule->params[smoothParamId];
  175. float value = smoothParam->value;
  176. // Use decay rate of roughly 1 graphics frame
  177. const float smoothLambda = 60.f;
  178. float newValue = value + (smoothValue - value) * smoothLambda * internal->sampleTime;
  179. if (value == newValue) {
  180. // Snap to actual smooth value if the value doesn't change enough (due to the granularity of floats)
  181. smoothParam->setValue(smoothValue);
  182. internal->smoothModule = NULL;
  183. internal->smoothParamId = 0;
  184. }
  185. else {
  186. smoothParam->setValue(newValue);
  187. }
  188. }
  189. // Step cables
  190. for (Cable* cable : internal->cables) {
  191. Cable_step(cable);
  192. }
  193. // Flip messages for each module
  194. for (Module* module : internal->modules) {
  195. if (module->leftExpander.messageFlipRequested) {
  196. std::swap(module->leftExpander.producerMessage, module->leftExpander.consumerMessage);
  197. module->leftExpander.messageFlipRequested = false;
  198. }
  199. if (module->rightExpander.messageFlipRequested) {
  200. std::swap(module->rightExpander.producerMessage, module->rightExpander.consumerMessage);
  201. module->rightExpander.messageFlipRequested = false;
  202. }
  203. }
  204. // Build ProcessArgs
  205. Module::ProcessArgs processArgs;
  206. processArgs.sampleRate = internal->sampleRate;
  207. processArgs.sampleTime = internal->sampleTime;
  208. processArgs.frame = internal->frame;
  209. // Step each module
  210. for (Module* module : internal->modules) {
  211. module->doProcess(processArgs);
  212. }
  213. ++internal->frame;
  214. }
  215. static void Port_setDisconnected(Port* that) {
  216. that->channels = 0;
  217. for (int c = 0; c < PORT_MAX_CHANNELS; c++) {
  218. that->voltages[c] = 0.f;
  219. }
  220. }
  221. static void Port_setConnected(Port* that) {
  222. if (that->channels > 0)
  223. return;
  224. that->channels = 1;
  225. }
  226. static void Engine_updateConnected(Engine* that) {
  227. // Find disconnected ports
  228. std::set<Port*> disconnectedPorts;
  229. for (Module* module : that->internal->modules) {
  230. for (Input& input : module->inputs) {
  231. disconnectedPorts.insert(&input);
  232. }
  233. for (Output& output : module->outputs) {
  234. disconnectedPorts.insert(&output);
  235. }
  236. }
  237. for (Cable* cable : that->internal->cables) {
  238. // Connect input
  239. Input& input = cable->inputModule->inputs[cable->inputId];
  240. auto inputIt = disconnectedPorts.find(&input);
  241. if (inputIt != disconnectedPorts.end())
  242. disconnectedPorts.erase(inputIt);
  243. Port_setConnected(&input);
  244. // Connect output
  245. Output& output = cable->outputModule->outputs[cable->outputId];
  246. auto outputIt = disconnectedPorts.find(&output);
  247. if (outputIt != disconnectedPorts.end())
  248. disconnectedPorts.erase(outputIt);
  249. Port_setConnected(&output);
  250. }
  251. // Disconnect ports that have no cable
  252. for (Port* port : disconnectedPorts) {
  253. Port_setDisconnected(port);
  254. }
  255. }
  256. static void Engine_refreshParamHandleCache(Engine* that) {
  257. // Clear cache
  258. that->internal->paramHandlesCache.clear();
  259. // Add active ParamHandles to cache
  260. for (ParamHandle* paramHandle : that->internal->paramHandles) {
  261. if (paramHandle->moduleId >= 0) {
  262. that->internal->paramHandlesCache[std::make_tuple(paramHandle->moduleId, paramHandle->paramId)] = paramHandle;
  263. }
  264. }
  265. }
  266. Engine::Engine() {
  267. internal = new Internal;
  268. }
  269. Engine::~Engine() {
  270. // Clear modules, cables, etc
  271. clear();
  272. // Make sure there are no cables or modules in the rack on destruction.
  273. // If this happens, a module must have failed to remove itself before the RackWidget was destroyed.
  274. DISTRHO_SAFE_ASSERT(internal->cables.empty());
  275. DISTRHO_SAFE_ASSERT(internal->modules.empty());
  276. DISTRHO_SAFE_ASSERT(internal->paramHandles.empty());
  277. DISTRHO_SAFE_ASSERT(internal->modulesCache.empty());
  278. DISTRHO_SAFE_ASSERT(internal->cablesCache.empty());
  279. DISTRHO_SAFE_ASSERT(internal->paramHandlesCache.empty());
  280. delete internal;
  281. }
  282. void Engine::clear() {
  283. WriteLock lock(internal->mutex);
  284. clear_NoLock();
  285. }
  286. void Engine::clear_NoLock() {
  287. // Copy lists because we'll be removing while iterating
  288. std::set<ParamHandle*> paramHandles = internal->paramHandles;
  289. for (ParamHandle* paramHandle : paramHandles) {
  290. removeParamHandle_NoLock(paramHandle);
  291. // Don't delete paramHandle because they're normally owned by Module subclasses
  292. }
  293. std::vector<Cable*> cables = internal->cables;
  294. for (Cable* cable : cables) {
  295. removeCable_NoLock(cable);
  296. delete cable;
  297. }
  298. std::vector<Module*> modules = internal->modules;
  299. for (Module* module : modules) {
  300. removeModule_NoLock(module);
  301. delete module;
  302. }
  303. }
  304. void Engine::stepBlock(int frames) {
  305. // Start timer before locking
  306. double startTime = system::getTime();
  307. ReadLock lock(internal->mutex);
  308. // Configure thread
  309. random::init();
  310. internal->blockFrame = internal->frame;
  311. internal->blockTime = system::getTime();
  312. internal->blockFrames = frames;
  313. // Update expander pointers
  314. for (Module* module : internal->modules) {
  315. Engine_updateExpander_NoLock(this, module, false);
  316. Engine_updateExpander_NoLock(this, module, true);
  317. }
  318. // Step individual frames
  319. for (int i = 0; i < frames; i++) {
  320. Engine_stepFrame(this);
  321. }
  322. internal->block++;
  323. // Stop timer
  324. double endTime = system::getTime();
  325. double meter = (endTime - startTime) / (frames * internal->sampleTime);
  326. internal->meterTotal += meter;
  327. internal->meterMax = std::fmax(internal->meterMax, meter);
  328. internal->meterCount++;
  329. // Update meter values
  330. const double meterUpdateDuration = 1.0;
  331. if (startTime - internal->meterLastTime >= meterUpdateDuration) {
  332. internal->meterLastAverage = internal->meterTotal / internal->meterCount;
  333. internal->meterLastMax = internal->meterMax;
  334. internal->meterLastTime = startTime;
  335. internal->meterCount = 0;
  336. internal->meterTotal = 0.0;
  337. internal->meterMax = 0.0;
  338. }
  339. }
  340. void Engine::setMasterModule(Module* module) {
  341. }
  342. void Engine::setMasterModule_NoLock(Module* module) {
  343. }
  344. Module* Engine::getMasterModule() {
  345. return nullptr;
  346. }
  347. float Engine::getSampleRate() {
  348. return internal->sampleRate;
  349. }
  350. void Engine::setSampleRate(float sampleRate) {
  351. if (sampleRate == internal->sampleRate)
  352. return;
  353. WriteLock lock(internal->mutex);
  354. internal->sampleRate = sampleRate;
  355. internal->sampleTime = 1.f / sampleRate;
  356. // Dispatch SampleRateChangeEvent
  357. Module::SampleRateChangeEvent e;
  358. e.sampleRate = internal->sampleRate;
  359. e.sampleTime = internal->sampleTime;
  360. for (Module* module : internal->modules) {
  361. module->onSampleRateChange(e);
  362. }
  363. }
  364. void Engine::setSuggestedSampleRate(float suggestedSampleRate) {
  365. }
  366. float Engine::getSampleTime() {
  367. return internal->sampleTime;
  368. }
  369. void Engine::yieldWorkers() {
  370. }
  371. int64_t Engine::getBlock() {
  372. return internal->block;
  373. }
  374. int64_t Engine::getFrame() {
  375. return internal->frame;
  376. }
  377. void Engine::setFrame(int64_t frame) {
  378. internal->frame = frame;
  379. }
  380. int64_t Engine::getBlockFrame() {
  381. return internal->blockFrame;
  382. }
  383. double Engine::getBlockTime() {
  384. return internal->blockTime;
  385. }
  386. int Engine::getBlockFrames() {
  387. return internal->blockFrames;
  388. }
  389. double Engine::getBlockDuration() {
  390. return internal->blockFrames * internal->sampleTime;
  391. }
  392. double Engine::getMeterAverage() {
  393. return internal->meterLastAverage;
  394. }
  395. double Engine::getMeterMax() {
  396. return internal->meterLastMax;
  397. }
  398. size_t Engine::getNumModules() {
  399. return internal->modules.size();
  400. }
  401. size_t Engine::getModuleIds(int64_t* moduleIds, size_t len) {
  402. ReadLock lock(internal->mutex);
  403. size_t i = 0;
  404. for (Module* m : internal->modules) {
  405. if (i >= len)
  406. break;
  407. moduleIds[i] = m->id;
  408. i++;
  409. }
  410. return i;
  411. }
  412. std::vector<int64_t> Engine::getModuleIds() {
  413. ReadLock lock(internal->mutex);
  414. std::vector<int64_t> moduleIds;
  415. moduleIds.reserve(internal->modules.size());
  416. for (Module* m : internal->modules) {
  417. moduleIds.push_back(m->id);
  418. }
  419. return moduleIds;
  420. }
  421. void Engine::addModule(Module* module) {
  422. WriteLock lock(internal->mutex);
  423. DISTRHO_SAFE_ASSERT_RETURN(module,);
  424. // Check that the module is not already added
  425. auto it = std::find(internal->modules.begin(), internal->modules.end(), module);
  426. DISTRHO_SAFE_ASSERT_RETURN(it == internal->modules.end(),);
  427. // Set ID if unset or collides with an existing ID
  428. while (module->id < 0 || internal->modulesCache.find(module->id) != internal->modulesCache.end()) {
  429. // Randomly generate ID
  430. module->id = random::u64() % (1ull << 53);
  431. }
  432. // Add module
  433. internal->modules.push_back(module);
  434. internal->modulesCache[module->id] = module;
  435. // Dispatch AddEvent
  436. Module::AddEvent eAdd;
  437. module->onAdd(eAdd);
  438. // Dispatch SampleRateChangeEvent
  439. Module::SampleRateChangeEvent eSrc;
  440. eSrc.sampleRate = internal->sampleRate;
  441. eSrc.sampleTime = internal->sampleTime;
  442. module->onSampleRateChange(eSrc);
  443. // Update ParamHandles' module pointers
  444. for (ParamHandle* paramHandle : internal->paramHandles) {
  445. if (paramHandle->moduleId == module->id)
  446. paramHandle->module = module;
  447. }
  448. }
  449. void Engine::removeModule(Module* module) {
  450. WriteLock lock(internal->mutex);
  451. removeModule_NoLock(module);
  452. }
  453. void Engine::removeModule_NoLock(Module* module) {
  454. DISTRHO_SAFE_ASSERT_RETURN(module,);
  455. // Check that the module actually exists
  456. auto it = std::find(internal->modules.begin(), internal->modules.end(), module);
  457. DISTRHO_SAFE_ASSERT_RETURN(it != internal->modules.end(),);
  458. // Remove from widgets cache
  459. CardinalPluginModelHelper* const helper = dynamic_cast<CardinalPluginModelHelper*>(module->model);
  460. DISTRHO_SAFE_ASSERT_RETURN(helper != nullptr,);
  461. helper->removeCachedModuleWidget(module);
  462. // Dispatch RemoveEvent
  463. Module::RemoveEvent eRemove;
  464. module->onRemove(eRemove);
  465. // Update ParamHandles' module pointers
  466. for (ParamHandle* paramHandle : internal->paramHandles) {
  467. if (paramHandle->moduleId == module->id)
  468. paramHandle->module = NULL;
  469. }
  470. // If a param is being smoothed on this module, stop smoothing it immediately
  471. if (module == internal->smoothModule) {
  472. internal->smoothModule = NULL;
  473. }
  474. // Check that all cables are disconnected
  475. for (Cable* cable : internal->cables) {
  476. DISTRHO_SAFE_ASSERT(cable->inputModule != module);
  477. DISTRHO_SAFE_ASSERT(cable->outputModule != module);
  478. }
  479. // Update expanders of other modules
  480. for (Module* m : internal->modules) {
  481. if (m->leftExpander.module == module) {
  482. m->leftExpander.moduleId = -1;
  483. m->leftExpander.module = NULL;
  484. }
  485. if (m->rightExpander.module == module) {
  486. m->rightExpander.moduleId = -1;
  487. m->rightExpander.module = NULL;
  488. }
  489. }
  490. // Remove module
  491. internal->modulesCache.erase(module->id);
  492. internal->modules.erase(it);
  493. // Reset expanders
  494. module->leftExpander.moduleId = -1;
  495. module->leftExpander.module = NULL;
  496. module->rightExpander.moduleId = -1;
  497. module->rightExpander.module = NULL;
  498. }
  499. bool Engine::hasModule(Module* module) {
  500. ReadLock lock(internal->mutex);
  501. // TODO Performance could be improved by searching modulesCache, but more testing would be needed to make sure it's always valid.
  502. auto it = std::find(internal->modules.begin(), internal->modules.end(), module);
  503. return it != internal->modules.end();
  504. }
  505. Module* Engine::getModule(int64_t moduleId) {
  506. ReadLock lock(internal->mutex);
  507. return getModule_NoLock(moduleId);
  508. }
  509. Module* Engine::getModule_NoLock(int64_t moduleId) {
  510. auto it = internal->modulesCache.find(moduleId);
  511. if (it == internal->modulesCache.end())
  512. return NULL;
  513. return it->second;
  514. }
  515. void Engine::resetModule(Module* module) {
  516. WriteLock lock(internal->mutex);
  517. DISTRHO_SAFE_ASSERT_RETURN(module,);
  518. Module::ResetEvent eReset;
  519. module->onReset(eReset);
  520. }
  521. void Engine::randomizeModule(Module* module) {
  522. WriteLock lock(internal->mutex);
  523. DISTRHO_SAFE_ASSERT_RETURN(module,);
  524. Module::RandomizeEvent eRandomize;
  525. module->onRandomize(eRandomize);
  526. }
  527. void Engine::bypassModule(Module* module, bool bypassed) {
  528. DISTRHO_SAFE_ASSERT_RETURN(module,);
  529. if (module->isBypassed() == bypassed)
  530. return;
  531. WriteLock lock(internal->mutex);
  532. // Clear outputs and set to 1 channel
  533. for (Output& output : module->outputs) {
  534. // This zeros all voltages, but the channel is set to 1 if connected
  535. output.setChannels(0);
  536. }
  537. // Set bypassed state
  538. module->setBypassed(bypassed);
  539. if (bypassed) {
  540. // Dispatch BypassEvent
  541. Module::BypassEvent eBypass;
  542. module->onBypass(eBypass);
  543. }
  544. else {
  545. // Dispatch UnBypassEvent
  546. Module::UnBypassEvent eUnBypass;
  547. module->onUnBypass(eUnBypass);
  548. }
  549. }
  550. json_t* Engine::moduleToJson(Module* module) {
  551. ReadLock lock(internal->mutex);
  552. return module->toJson();
  553. }
  554. void Engine::moduleFromJson(Module* module, json_t* rootJ) {
  555. WriteLock lock(internal->mutex);
  556. module->fromJson(rootJ);
  557. }
  558. void Engine::prepareSaveModule(Module* module) {
  559. ReadLock lock(internal->mutex);
  560. Module::SaveEvent e;
  561. module->onSave(e);
  562. }
  563. void Engine::prepareSave() {
  564. ReadLock lock(internal->mutex);
  565. for (Module* module : internal->modules) {
  566. Module::SaveEvent e;
  567. module->onSave(e);
  568. }
  569. }
  570. size_t Engine::getNumCables() {
  571. return internal->cables.size();
  572. }
  573. size_t Engine::getCableIds(int64_t* cableIds, size_t len) {
  574. ReadLock lock(internal->mutex);
  575. size_t i = 0;
  576. for (Cable* c : internal->cables) {
  577. if (i >= len)
  578. break;
  579. cableIds[i] = c->id;
  580. i++;
  581. }
  582. return i;
  583. }
  584. std::vector<int64_t> Engine::getCableIds() {
  585. ReadLock lock(internal->mutex);
  586. std::vector<int64_t> cableIds;
  587. cableIds.reserve(internal->cables.size());
  588. for (Cable* c : internal->cables) {
  589. cableIds.push_back(c->id);
  590. }
  591. return cableIds;
  592. }
  593. void Engine::addCable(Cable* cable) {
  594. WriteLock lock(internal->mutex);
  595. DISTRHO_SAFE_ASSERT_RETURN(cable,);
  596. // Check cable properties
  597. DISTRHO_SAFE_ASSERT_RETURN(cable->inputModule,);
  598. DISTRHO_SAFE_ASSERT_RETURN(cable->outputModule,);
  599. bool outputWasConnected = false;
  600. for (Cable* cable2 : internal->cables) {
  601. // Check that the cable is not already added
  602. DISTRHO_SAFE_ASSERT_RETURN(cable2 != cable,);
  603. // Check that the input is not already used by another cable
  604. DISTRHO_SAFE_ASSERT_RETURN(!(cable2->inputModule == cable->inputModule && cable2->inputId == cable->inputId),);
  605. // Get connected status of output, to decide whether we need to call a PortChangeEvent.
  606. // It's best to not trust `cable->outputModule->outputs[cable->outputId]->isConnected()`
  607. if (cable2->outputModule == cable->outputModule && cable2->outputId == cable->outputId)
  608. outputWasConnected = true;
  609. }
  610. // Set ID if unset or collides with an existing ID
  611. while (cable->id < 0 || internal->cablesCache.find(cable->id) != internal->cablesCache.end()) {
  612. // Randomly generate ID
  613. cable->id = random::u64() % (1ull << 53);
  614. }
  615. // Add the cable
  616. internal->cables.push_back(cable);
  617. internal->cablesCache[cable->id] = cable;
  618. Engine_updateConnected(this);
  619. // Dispatch input port event
  620. {
  621. Module::PortChangeEvent e;
  622. e.connecting = true;
  623. e.type = Port::INPUT;
  624. e.portId = cable->inputId;
  625. cable->inputModule->onPortChange(e);
  626. }
  627. // Dispatch output port event if its state went from disconnected to connected.
  628. if (!outputWasConnected) {
  629. Module::PortChangeEvent e;
  630. e.connecting = true;
  631. e.type = Port::OUTPUT;
  632. e.portId = cable->outputId;
  633. cable->outputModule->onPortChange(e);
  634. }
  635. }
  636. void Engine::removeCable(Cable* cable) {
  637. WriteLock lock(internal->mutex);
  638. removeCable_NoLock(cable);
  639. }
  640. void Engine::removeCable_NoLock(Cable* cable) {
  641. DISTRHO_SAFE_ASSERT_RETURN(cable,);
  642. // Check that the cable is already added
  643. auto it = std::find(internal->cables.begin(), internal->cables.end(), cable);
  644. DISTRHO_SAFE_ASSERT_RETURN(it != internal->cables.end(),);
  645. // Remove the cable
  646. internal->cablesCache.erase(cable->id);
  647. internal->cables.erase(it);
  648. Engine_updateConnected(this);
  649. bool outputIsConnected = false;
  650. for (Cable* cable2 : internal->cables) {
  651. // Get connected status of output, to decide whether we need to call a PortChangeEvent.
  652. // It's best to not trust `cable->outputModule->outputs[cable->outputId]->isConnected()`
  653. if (cable2->outputModule == cable->outputModule && cable2->outputId == cable->outputId)
  654. outputIsConnected = true;
  655. }
  656. // Dispatch input port event
  657. {
  658. Module::PortChangeEvent e;
  659. e.connecting = false;
  660. e.type = Port::INPUT;
  661. e.portId = cable->inputId;
  662. cable->inputModule->onPortChange(e);
  663. }
  664. // Dispatch output port event if its state went from connected to disconnected.
  665. if (!outputIsConnected) {
  666. Module::PortChangeEvent e;
  667. e.connecting = false;
  668. e.type = Port::OUTPUT;
  669. e.portId = cable->outputId;
  670. cable->outputModule->onPortChange(e);
  671. }
  672. }
  673. bool Engine::hasCable(Cable* cable) {
  674. ReadLock lock(internal->mutex);
  675. // TODO Performance could be improved by searching cablesCache, but more testing would be needed to make sure it's always valid.
  676. auto it = std::find(internal->cables.begin(), internal->cables.end(), cable);
  677. return it != internal->cables.end();
  678. }
  679. Cable* Engine::getCable(int64_t cableId) {
  680. ReadLock lock(internal->mutex);
  681. auto it = internal->cablesCache.find(cableId);
  682. if (it == internal->cablesCache.end())
  683. return NULL;
  684. return it->second;
  685. }
  686. void Engine::setParamValue(Module* module, int paramId, float value) {
  687. // If param is being smoothed, cancel smoothing.
  688. if (internal->smoothModule == module && internal->smoothParamId == paramId) {
  689. internal->smoothModule = NULL;
  690. internal->smoothParamId = 0;
  691. }
  692. module->params[paramId].value = value;
  693. }
  694. float Engine::getParamValue(Module* module, int paramId) {
  695. return module->params[paramId].value;
  696. }
  697. void Engine::setParamSmoothValue(Module* module, int paramId, float value) {
  698. // If another param is being smoothed, jump value
  699. if (internal->smoothModule && !(internal->smoothModule == module && internal->smoothParamId == paramId)) {
  700. internal->smoothModule->params[internal->smoothParamId].value = internal->smoothValue;
  701. }
  702. internal->smoothParamId = paramId;
  703. internal->smoothValue = value;
  704. // Set this last so the above values are valid as soon as it is set
  705. internal->smoothModule = module;
  706. }
  707. float Engine::getParamSmoothValue(Module* module, int paramId) {
  708. if (internal->smoothModule == module && internal->smoothParamId == paramId)
  709. return internal->smoothValue;
  710. return module->params[paramId].value;
  711. }
  712. void Engine::addParamHandle(ParamHandle* paramHandle) {
  713. WriteLock lock(internal->mutex);
  714. // New ParamHandles must be blank.
  715. // This means we don't have to refresh the cache.
  716. DISTRHO_SAFE_ASSERT_RETURN(paramHandle->moduleId < 0,);
  717. // Check that the ParamHandle is not already added
  718. auto it = internal->paramHandles.find(paramHandle);
  719. DISTRHO_SAFE_ASSERT_RETURN(it == internal->paramHandles.end(),);
  720. // Add it
  721. internal->paramHandles.insert(paramHandle);
  722. // No need to refresh the cache because the moduleId is not set.
  723. }
  724. void Engine::removeParamHandle(ParamHandle* paramHandle) {
  725. WriteLock lock(internal->mutex);
  726. removeParamHandle_NoLock(paramHandle);
  727. }
  728. void Engine::removeParamHandle_NoLock(ParamHandle* paramHandle) {
  729. // Check that the ParamHandle is already added
  730. auto it = internal->paramHandles.find(paramHandle);
  731. DISTRHO_SAFE_ASSERT_RETURN(it != internal->paramHandles.end(),);
  732. // Remove it
  733. paramHandle->module = NULL;
  734. internal->paramHandles.erase(it);
  735. Engine_refreshParamHandleCache(this);
  736. }
  737. ParamHandle* Engine::getParamHandle(int64_t moduleId, int paramId) {
  738. ReadLock lock(internal->mutex);
  739. return getParamHandle_NoLock(moduleId, paramId);
  740. }
  741. ParamHandle* Engine::getParamHandle_NoLock(int64_t moduleId, int paramId) {
  742. auto it = internal->paramHandlesCache.find(std::make_tuple(moduleId, paramId));
  743. if (it == internal->paramHandlesCache.end())
  744. return NULL;
  745. return it->second;
  746. }
  747. ParamHandle* Engine::getParamHandle(Module* module, int paramId) {
  748. return getParamHandle(module->id, paramId);
  749. }
  750. void Engine::updateParamHandle(ParamHandle* paramHandle, int64_t moduleId, int paramId, bool overwrite) {
  751. WriteLock lock(internal->mutex);
  752. updateParamHandle_NoLock(paramHandle, moduleId, paramId, overwrite);
  753. }
  754. void Engine::updateParamHandle_NoLock(ParamHandle* paramHandle, int64_t moduleId, int paramId, bool overwrite) {
  755. // Check that it exists
  756. auto it = internal->paramHandles.find(paramHandle);
  757. DISTRHO_SAFE_ASSERT_RETURN(it != internal->paramHandles.end(),);
  758. // Set IDs
  759. paramHandle->moduleId = moduleId;
  760. paramHandle->paramId = paramId;
  761. paramHandle->module = NULL;
  762. // At this point, the ParamHandle cache might be invalid.
  763. if (paramHandle->moduleId >= 0) {
  764. // Replace old ParamHandle, or reset the current ParamHandle
  765. ParamHandle* oldParamHandle = getParamHandle_NoLock(moduleId, paramId);
  766. if (oldParamHandle) {
  767. if (overwrite) {
  768. oldParamHandle->moduleId = -1;
  769. oldParamHandle->paramId = 0;
  770. oldParamHandle->module = NULL;
  771. }
  772. else {
  773. paramHandle->moduleId = -1;
  774. paramHandle->paramId = 0;
  775. paramHandle->module = NULL;
  776. }
  777. }
  778. }
  779. // Set module pointer if the above block didn't reset it
  780. if (paramHandle->moduleId >= 0) {
  781. paramHandle->module = getModule_NoLock(paramHandle->moduleId);
  782. }
  783. Engine_refreshParamHandleCache(this);
  784. }
  785. json_t* Engine::toJson() {
  786. ReadLock lock(internal->mutex);
  787. json_t* rootJ = json_object();
  788. // modules
  789. json_t* modulesJ = json_array();
  790. for (Module* module : internal->modules) {
  791. json_t* moduleJ = module->toJson();
  792. json_array_append_new(modulesJ, moduleJ);
  793. }
  794. json_object_set_new(rootJ, "modules", modulesJ);
  795. // cables
  796. json_t* cablesJ = json_array();
  797. for (Cable* cable : internal->cables) {
  798. json_t* cableJ = cable->toJson();
  799. json_array_append_new(cablesJ, cableJ);
  800. }
  801. json_object_set_new(rootJ, "cables", cablesJ);
  802. return rootJ;
  803. }
  804. void Engine::fromJson(json_t* rootJ) {
  805. // Don't write-lock the entire method because most of it doesn't need it.
  806. // Write-locks
  807. clear();
  808. // modules
  809. json_t* modulesJ = json_object_get(rootJ, "modules");
  810. if (!modulesJ)
  811. return;
  812. size_t moduleIndex;
  813. json_t* moduleJ;
  814. json_array_foreach(modulesJ, moduleIndex, moduleJ) {
  815. // Get model
  816. plugin::Model* model;
  817. try {
  818. model = plugin::modelFromJson(moduleJ);
  819. }
  820. catch (Exception& e) {
  821. WARN("Cannot load model: %s", e.what());
  822. // APP->patch->log(e.what());
  823. continue;
  824. }
  825. // Create module
  826. Module* const module = model->createModule();
  827. DISTRHO_SAFE_ASSERT_CONTINUE(module != nullptr);
  828. // Create the widget too, needed by a few modules
  829. CardinalPluginModelHelper* const helper = dynamic_cast<CardinalPluginModelHelper*>(model);
  830. DISTRHO_SAFE_ASSERT_CONTINUE(helper != nullptr);
  831. app::ModuleWidget* const moduleWidget = helper->createModuleWidgetFromEngineLoad(module);
  832. DISTRHO_SAFE_ASSERT_CONTINUE(moduleWidget != nullptr);
  833. try {
  834. // This doesn't need a lock because the Module is not added to the Engine yet.
  835. module->fromJson(moduleJ);
  836. // Before 1.0, the module ID was the index in the "modules" array
  837. if (module->id < 0) {
  838. module->id = moduleIndex;
  839. }
  840. // Write-locks
  841. addModule(module);
  842. }
  843. catch (Exception& e) {
  844. WARN("Cannot load module: %s", e.what());
  845. // APP->patch->log(e.what());
  846. helper->removeCachedModuleWidget(module);
  847. delete module;
  848. continue;
  849. }
  850. }
  851. // cables
  852. json_t* cablesJ = json_object_get(rootJ, "cables");
  853. // Before 1.0, cables were called wires
  854. if (!cablesJ)
  855. cablesJ = json_object_get(rootJ, "wires");
  856. if (!cablesJ)
  857. return;
  858. size_t cableIndex;
  859. json_t* cableJ;
  860. json_array_foreach(cablesJ, cableIndex, cableJ) {
  861. // cable
  862. Cable* cable = new Cable;
  863. try {
  864. cable->fromJson(cableJ);
  865. // Before 1.0, the cable ID was the index in the "cables" array
  866. if (cable->id < 0) {
  867. cable->id = cableIndex;
  868. }
  869. // Write-locks
  870. addCable(cable);
  871. }
  872. catch (Exception& e) {
  873. WARN("Cannot load cable: %s", e.what());
  874. delete cable;
  875. // Don't log exceptions because missing modules create unnecessary complaining when cables try to connect to them.
  876. continue;
  877. }
  878. }
  879. }
  880. void Engine::startFallbackThread() {
  881. }
  882. } // namespace engine
  883. } // namespace rack