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.

1357 lines
38KB

  1. /*
  2. * DISTRHO Cardinal Plugin
  3. * Copyright (C) 2021-2023 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/Engine.cpp
  19. * Copyright (C) 2016-2023 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 <unordered_map>
  35. #include <engine/Engine.hpp>
  36. #include <engine/TerminalModule.hpp>
  37. #include <settings.hpp>
  38. #include <system.hpp>
  39. #include <random.hpp>
  40. #include <patch.hpp>
  41. #include <plugin.hpp>
  42. #include <mutex.hpp>
  43. #include <helpers.hpp>
  44. #ifdef NDEBUG
  45. # undef DEBUG
  46. #endif
  47. #include "../CardinalRemote.hpp"
  48. #include "DistrhoUtils.hpp"
  49. // known terminal modules
  50. extern std::vector<rack::plugin::Model*> hostTerminalModels;
  51. namespace rack {
  52. namespace engine {
  53. static constexpr const int PORT_DIVIDER = 7;
  54. // Arbitrary prime number so it doesn't over- or under-estimate time of buffered processors.
  55. static constexpr const int METER_DIVIDER = 37;
  56. static constexpr const int METER_BUFFER_LEN = 32;
  57. static constexpr const float METER_TIME = 1.f;
  58. struct Engine::Internal {
  59. std::vector<Module*> modules;
  60. std::vector<TerminalModule*> terminalModules;
  61. std::vector<Cable*> cables;
  62. std::set<ParamHandle*> paramHandles;
  63. // moduleId
  64. std::map<int64_t, Module*> modulesCache;
  65. // cableId
  66. std::map<int64_t, Cable*> cablesCache;
  67. // (moduleId, paramId)
  68. std::map<std::tuple<int64_t, int>, ParamHandle*> paramHandlesCache;
  69. float sampleRate = 0.f;
  70. float sampleTime = 0.f;
  71. int64_t frame = 0;
  72. int64_t block = 0;
  73. int64_t blockFrame = 0;
  74. double blockTime = 0.0;
  75. int blockFrames = 0;
  76. bool aboutToClose = false;
  77. #ifndef HEADLESS
  78. // Meter
  79. int meterCount = 0;
  80. double meterTotal = 0.0;
  81. double meterMax = 0.0;
  82. double meterLastTime = -INFINITY;
  83. double meterLastAverage = 0.0;
  84. double meterLastMax = 0.0;
  85. #endif
  86. // Parameter smoothing
  87. Module* smoothModule = NULL;
  88. int smoothParamId = 0;
  89. float smoothValue = 0.f;
  90. // Remote control
  91. remoteUtils::RemoteDetails* remoteDetails = nullptr;
  92. /** Mutex that guards the Engine state, such as settings, Modules, and Cables.
  93. Writers lock when mutating the engine's state or stepping the block.
  94. Readers lock when using the engine's state.
  95. */
  96. SharedMutex mutex;
  97. };
  98. struct Module::Internal {
  99. bool bypassed = false;
  100. int meterSamples = 0;
  101. float meterDurationTotal = 0.f;
  102. float meterBuffer[METER_BUFFER_LEN] = {};
  103. int meterIndex = 0;
  104. };
  105. static void Engine_updateExpander_NoLock(Engine* that, Module* module, bool side) {
  106. Module::Expander& expander = side ? module->rightExpander : module->leftExpander;
  107. Module* oldExpanderModule = expander.module;
  108. if (expander.moduleId >= 0) {
  109. if (!expander.module || expander.module->id != expander.moduleId) {
  110. expander.module = that->getModule_NoLock(expander.moduleId);
  111. }
  112. }
  113. else {
  114. if (expander.module) {
  115. expander.module = NULL;
  116. }
  117. }
  118. if (expander.module != oldExpanderModule) {
  119. // Dispatch ExpanderChangeEvent
  120. Module::ExpanderChangeEvent e;
  121. e.side = side;
  122. module->onExpanderChange(e);
  123. }
  124. }
  125. static void Cable_step(Cable* that) {
  126. Output* output = &that->outputModule->outputs[that->outputId];
  127. Input* input = &that->inputModule->inputs[that->inputId];
  128. // Match number of polyphonic channels to output port
  129. const int channels = output->channels;
  130. // Copy all voltages from output to input
  131. for (int c = 0; c < channels; c++) {
  132. if (!std::isfinite(output->voltages[c]))
  133. __builtin_unreachable();
  134. input->voltages[c] = output->voltages[c];
  135. }
  136. // Set higher channel voltages to 0
  137. for (int c = channels; c < input->channels; c++) {
  138. input->voltages[c] = 0.f;
  139. }
  140. input->channels = channels;
  141. }
  142. #ifndef HEADLESS
  143. static void Port_step(Port* that, float deltaTime) {
  144. // Set plug lights
  145. if (that->channels == 0) {
  146. that->plugLights[0].setBrightness(0.f);
  147. that->plugLights[1].setBrightness(0.f);
  148. that->plugLights[2].setBrightness(0.f);
  149. }
  150. else if (that->channels == 1) {
  151. float v = that->getVoltage() / 10.f;
  152. that->plugLights[0].setSmoothBrightness(-v, deltaTime);
  153. that->plugLights[1].setSmoothBrightness(v, deltaTime);
  154. that->plugLights[2].setBrightness(0.f);
  155. }
  156. else {
  157. float v = that->getVoltageRMS() / 10.f;
  158. that->plugLights[0].setBrightness(0.f);
  159. that->plugLights[1].setBrightness(0.f);
  160. that->plugLights[2].setSmoothBrightness(v, deltaTime);
  161. }
  162. }
  163. #endif
  164. static void TerminalModule__doProcess(TerminalModule* const terminalModule, const Module::ProcessArgs& args, bool input) {
  165. // Step module
  166. if (input) {
  167. terminalModule->processTerminalInput(args);
  168. for (Output& output : terminalModule->outputs) {
  169. for (Cable* cable : output.cables)
  170. Cable_step(cable);
  171. }
  172. } else {
  173. terminalModule->processTerminalOutput(args);
  174. }
  175. #ifndef HEADLESS
  176. // Iterate ports to step plug lights
  177. if (args.frame % PORT_DIVIDER == 0) {
  178. float portTime = args.sampleTime * PORT_DIVIDER;
  179. for (Input& input : terminalModule->inputs) {
  180. Port_step(&input, portTime);
  181. }
  182. for (Output& output : terminalModule->outputs) {
  183. Port_step(&output, portTime);
  184. }
  185. }
  186. #endif
  187. }
  188. static void Module__doProcess(Module* const module, const Module::ProcessArgs& args) {
  189. Module::Internal* const internal = module->internal;
  190. #ifndef HEADLESS
  191. // This global setting can change while the function is running, so use a local variable.
  192. bool meterEnabled = settings::cpuMeter && (args.frame % METER_DIVIDER == 0);
  193. // Start CPU timer
  194. double startTime;
  195. if (meterEnabled) {
  196. startTime = system::getTime();
  197. }
  198. #endif
  199. // Step module
  200. if (!internal->bypassed)
  201. module->process(args);
  202. else
  203. module->processBypass(args);
  204. #ifndef HEADLESS
  205. // Stop CPU timer
  206. if (meterEnabled) {
  207. double endTime = system::getTime();
  208. // Subtract call time of getTime() itself, since we only want to measure process() time.
  209. double endTime2 = system::getTime();
  210. float duration = (endTime - startTime) - (endTime2 - endTime);
  211. internal->meterSamples++;
  212. internal->meterDurationTotal += duration;
  213. // Seconds we've been measuring
  214. float meterTime = internal->meterSamples * METER_DIVIDER * args.sampleTime;
  215. if (meterTime >= METER_TIME) {
  216. // Push time to buffer
  217. if (internal->meterSamples > 0) {
  218. internal->meterIndex++;
  219. internal->meterIndex %= METER_BUFFER_LEN;
  220. internal->meterBuffer[internal->meterIndex] = internal->meterDurationTotal / internal->meterSamples;
  221. }
  222. // Reset total
  223. internal->meterSamples = 0;
  224. internal->meterDurationTotal = 0.f;
  225. }
  226. }
  227. // Iterate ports to step plug lights
  228. if (args.frame % PORT_DIVIDER == 0) {
  229. float portTime = args.sampleTime * PORT_DIVIDER;
  230. for (Input& input : module->inputs) {
  231. Port_step(&input, portTime);
  232. }
  233. for (Output& output : module->outputs) {
  234. Port_step(&output, portTime);
  235. }
  236. }
  237. #endif
  238. }
  239. /** Steps a single frame
  240. */
  241. static void Engine_stepFrame(Engine* that) {
  242. Engine::Internal* internal = that->internal;
  243. // Param smoothing
  244. Module* smoothModule = internal->smoothModule;
  245. if (smoothModule) {
  246. int smoothParamId = internal->smoothParamId;
  247. float smoothValue = internal->smoothValue;
  248. Param* smoothParam = &smoothModule->params[smoothParamId];
  249. float value = smoothParam->value;
  250. float newValue;
  251. if (internal->remoteDetails != nullptr) {
  252. newValue = value;
  253. sendParamChangeToRemote(internal->remoteDetails, smoothModule->id, smoothParamId, value);
  254. } else {
  255. // Use decay rate of roughly 1 graphics frame
  256. const float smoothLambda = 60.f;
  257. newValue = value + (smoothValue - value) * smoothLambda * internal->sampleTime;
  258. }
  259. if (d_isEqual(value, newValue)) {
  260. // Snap to actual smooth value if the value doesn't change enough (due to the granularity of floats)
  261. smoothParam->setValue(smoothValue);
  262. internal->smoothModule = NULL;
  263. internal->smoothParamId = 0;
  264. }
  265. else {
  266. smoothParam->setValue(newValue);
  267. }
  268. }
  269. // Flip messages for each module
  270. for (Module* module : internal->modules) {
  271. if (module->leftExpander.messageFlipRequested) {
  272. std::swap(module->leftExpander.producerMessage, module->leftExpander.consumerMessage);
  273. module->leftExpander.messageFlipRequested = false;
  274. }
  275. if (module->rightExpander.messageFlipRequested) {
  276. std::swap(module->rightExpander.producerMessage, module->rightExpander.consumerMessage);
  277. module->rightExpander.messageFlipRequested = false;
  278. }
  279. }
  280. // Build ProcessArgs
  281. Module::ProcessArgs processArgs;
  282. processArgs.sampleRate = internal->sampleRate;
  283. processArgs.sampleTime = internal->sampleTime;
  284. processArgs.frame = internal->frame;
  285. // Process terminal inputs first
  286. for (TerminalModule* terminalModule : internal->terminalModules) {
  287. TerminalModule__doProcess(terminalModule, processArgs, true);
  288. }
  289. // Step each module and cables
  290. for (Module* module : internal->modules) {
  291. Module__doProcess(module, processArgs);
  292. for (Output& output : module->outputs) {
  293. for (Cable* cable : output.cables)
  294. Cable_step(cable);
  295. }
  296. }
  297. // Process terminal outputs last
  298. for (TerminalModule* terminalModule : internal->terminalModules) {
  299. TerminalModule__doProcess(terminalModule, processArgs, false);
  300. }
  301. ++internal->frame;
  302. }
  303. static void Port_setDisconnected(Port* that) {
  304. that->channels = 0;
  305. for (int c = 0; c < PORT_MAX_CHANNELS; c++) {
  306. that->voltages[c] = 0.f;
  307. }
  308. }
  309. static void Port_setConnected(Port* that) {
  310. if (that->channels > 0)
  311. return;
  312. that->channels = 1;
  313. }
  314. template<typename T>
  315. using IdentityDictionary = std::unordered_map<T, T>;
  316. template<typename T>
  317. inline bool dictContains(IdentityDictionary<T>& dict, T key) {
  318. return dict.find(key) != dict.end();
  319. }
  320. template<typename T>
  321. inline void dictAdd(IdentityDictionary<T>& dict, T key) {
  322. dict[key] = key;
  323. }
  324. static void Engine_storeTerminalModulesIDs(std::vector<TerminalModule*> terminalModules, IdentityDictionary<int64_t>& terminalModulesIDs) {
  325. for (TerminalModule* terminalModule : terminalModules)
  326. dictAdd(terminalModulesIDs, terminalModule->id);
  327. }
  328. static void Engine_orderModule(Module* module, IdentityDictionary<Module*>& touchedModules, std::vector<Module*>& orderedModules, IdentityDictionary<int64_t>& terminalModulesIDs) {
  329. if (!dictContains(touchedModules, module) && !dictContains(terminalModulesIDs, module->id)) { // Ignore feedback loops and terminal modules
  330. dictAdd(touchedModules, module);
  331. for (Output& output : module->outputs) {
  332. for (Cable* cable : output.cables) {
  333. Module* receiver = cable->inputModule; // The input to the cable is the receiving module
  334. Engine_orderModule(receiver, touchedModules, orderedModules, terminalModulesIDs);
  335. }
  336. }
  337. orderedModules.push_back(module);
  338. }
  339. }
  340. static void Engine_assignOrderedModules(std::vector<Module*>& modules, std::vector<Module*>& orderedModules) {
  341. std::reverse(orderedModules.begin(), orderedModules.end()); // These are stored bottom up
  342. if (orderedModules.size() == modules.size()) {
  343. for (unsigned int i = 0; i < orderedModules.size(); i++)
  344. modules[i] = orderedModules[i];
  345. }
  346. }
  347. #if DEBUG_ORDERED_MODULES
  348. static void Engine_debugOrderedModules(std::vector<Module*>& modules) {
  349. printf("\n--- Ordered modules ---\n");
  350. for (unsigned int i = 0; i < modules.size(); i++)
  351. printf("%d) %s - %ld\n", i, modules[i]->model->getFullName().c_str(), modules[i]->id);
  352. }
  353. #endif
  354. /** Order the modules so that they always read the most recent sample from their inputs
  355. */
  356. static void Engine_orderModules(Engine* that) {
  357. Engine::Internal* internal = that->internal;
  358. IdentityDictionary<int64_t> terminalModulesIDs;
  359. Engine_storeTerminalModulesIDs(internal->terminalModules, terminalModulesIDs);
  360. IdentityDictionary<Module*> touchedModules;
  361. std::vector<Module*> orderedModules;
  362. orderedModules.reserve(internal->modules.size());
  363. for (Module* module : internal->modules)
  364. Engine_orderModule(module, touchedModules, orderedModules, terminalModulesIDs);
  365. Engine_assignOrderedModules(internal->modules, orderedModules);
  366. #if DEBUG_ORDERED_MODULES
  367. Engine_debugOrderedModules(internal->modules);
  368. #endif
  369. }
  370. static void Engine_updateConnected(Engine* that) {
  371. // Find disconnected ports
  372. std::set<Input*> disconnectedInputs;
  373. std::set<Output*> disconnectedOutputs;
  374. for (Module* module : that->internal->modules) {
  375. for (Input& input : module->inputs) {
  376. disconnectedInputs.insert(&input);
  377. }
  378. for (Output& output : module->outputs) {
  379. disconnectedOutputs.insert(&output);
  380. }
  381. }
  382. for (TerminalModule* terminalModule : that->internal->terminalModules) {
  383. for (Input& input : terminalModule->inputs) {
  384. disconnectedInputs.insert(&input);
  385. }
  386. for (Output& output : terminalModule->outputs) {
  387. disconnectedOutputs.insert(&output);
  388. }
  389. }
  390. for (Cable* cable : that->internal->cables) {
  391. // Connect input
  392. Input& input = cable->inputModule->inputs[cable->inputId];
  393. auto inputIt = disconnectedInputs.find(&input);
  394. if (inputIt != disconnectedInputs.end())
  395. disconnectedInputs.erase(inputIt);
  396. Port_setConnected(&input);
  397. // Connect output
  398. Output& output = cable->outputModule->outputs[cable->outputId];
  399. auto outputIt = disconnectedOutputs.find(&output);
  400. if (outputIt != disconnectedOutputs.end())
  401. disconnectedOutputs.erase(outputIt);
  402. Port_setConnected(&output);
  403. }
  404. // Disconnect ports that have no cable
  405. for (Input* input : disconnectedInputs) {
  406. Port_setDisconnected(input);
  407. }
  408. for (Output* output : disconnectedOutputs) {
  409. Port_setDisconnected(output);
  410. DISTRHO_SAFE_ASSERT(output->cables.empty());
  411. }
  412. // Order the modules according to their connections
  413. Engine_orderModules(that);
  414. }
  415. static void Engine_refreshParamHandleCache(Engine* that) {
  416. // Clear cache
  417. that->internal->paramHandlesCache.clear();
  418. // Add active ParamHandles to cache
  419. for (ParamHandle* paramHandle : that->internal->paramHandles) {
  420. if (paramHandle->moduleId >= 0) {
  421. that->internal->paramHandlesCache[std::make_tuple(paramHandle->moduleId, paramHandle->paramId)] = paramHandle;
  422. }
  423. }
  424. }
  425. Engine::Engine() {
  426. internal = new Internal;
  427. }
  428. Engine::~Engine() {
  429. // Clear modules, cables, etc
  430. clear();
  431. // Make sure there are no cables or modules in the rack on destruction.
  432. // If this happens, a module must have failed to remove itself before the RackWidget was destroyed.
  433. DISTRHO_SAFE_ASSERT(internal->cables.empty());
  434. DISTRHO_SAFE_ASSERT(internal->modules.empty());
  435. DISTRHO_SAFE_ASSERT(internal->terminalModules.empty());
  436. DISTRHO_SAFE_ASSERT(internal->paramHandles.empty());
  437. DISTRHO_SAFE_ASSERT(internal->modulesCache.empty());
  438. DISTRHO_SAFE_ASSERT(internal->cablesCache.empty());
  439. DISTRHO_SAFE_ASSERT(internal->paramHandlesCache.empty());
  440. delete internal;
  441. }
  442. void Engine::clear() {
  443. std::lock_guard<SharedMutex> lock(internal->mutex);
  444. clear_NoLock();
  445. }
  446. void Engine::clear_NoLock() {
  447. // Copy lists because we'll be removing while iterating
  448. std::set<ParamHandle*> paramHandles = internal->paramHandles;
  449. for (ParamHandle* paramHandle : paramHandles) {
  450. removeParamHandle_NoLock(paramHandle);
  451. // Don't delete paramHandle because they're normally owned by Module subclasses
  452. }
  453. std::vector<Cable*> cables = internal->cables;
  454. for (Cable* cable : cables) {
  455. removeCable_NoLock(cable);
  456. delete cable;
  457. }
  458. std::vector<Module*> modules = internal->modules;
  459. for (Module* module : modules) {
  460. removeModule_NoLock(module);
  461. delete module;
  462. }
  463. std::vector<TerminalModule*> terminalModules = internal->terminalModules;
  464. for (TerminalModule* terminalModule : terminalModules) {
  465. removeModule_NoLock(terminalModule);
  466. delete terminalModule;
  467. }
  468. }
  469. void Engine::stepBlock(int frames) {
  470. #ifndef HEADLESS
  471. // Start timer before locking
  472. double startTime = system::getTime();
  473. #endif
  474. SharedLock<SharedMutex> lock(internal->mutex);
  475. // Configure thread
  476. random::init();
  477. internal->blockFrame = internal->frame;
  478. internal->blockTime = system::getTime();
  479. internal->blockFrames = frames;
  480. // Update expander pointers
  481. for (Module* module : internal->modules) {
  482. Engine_updateExpander_NoLock(this, module, false);
  483. Engine_updateExpander_NoLock(this, module, true);
  484. }
  485. // Step individual frames
  486. for (int i = 0; i < frames; i++) {
  487. Engine_stepFrame(this);
  488. }
  489. internal->block++;
  490. #ifndef HEADLESS
  491. // Stop timer
  492. double endTime = system::getTime();
  493. double meter = (endTime - startTime) / (frames * internal->sampleTime);
  494. internal->meterTotal += meter;
  495. internal->meterMax = std::fmax(internal->meterMax, meter);
  496. internal->meterCount++;
  497. // Update meter values
  498. const double meterUpdateDuration = 1.0;
  499. if (startTime - internal->meterLastTime >= meterUpdateDuration) {
  500. internal->meterLastAverage = internal->meterTotal / internal->meterCount;
  501. internal->meterLastMax = internal->meterMax;
  502. internal->meterLastTime = startTime;
  503. internal->meterCount = 0;
  504. internal->meterTotal = 0.0;
  505. internal->meterMax = 0.0;
  506. }
  507. #endif
  508. }
  509. void Engine::setMasterModule(Module* module) {
  510. }
  511. void Engine::setMasterModule_NoLock(Module* module) {
  512. }
  513. Module* Engine::getMasterModule() {
  514. return nullptr;
  515. }
  516. float Engine::getSampleRate() {
  517. return internal->sampleRate;
  518. }
  519. void Engine::setSampleRate(float sampleRate) {
  520. if (sampleRate == internal->sampleRate)
  521. return;
  522. std::lock_guard<SharedMutex> lock(internal->mutex);
  523. internal->sampleRate = sampleRate;
  524. internal->sampleTime = 1.f / sampleRate;
  525. // Dispatch SampleRateChangeEvent
  526. Module::SampleRateChangeEvent e;
  527. e.sampleRate = internal->sampleRate;
  528. e.sampleTime = internal->sampleTime;
  529. for (Module* module : internal->modules) {
  530. module->onSampleRateChange(e);
  531. }
  532. for (TerminalModule* terminalModule : internal->terminalModules) {
  533. terminalModule->onSampleRateChange(e);
  534. }
  535. }
  536. void Engine::setSuggestedSampleRate(float suggestedSampleRate) {
  537. }
  538. float Engine::getSampleTime() {
  539. return internal->sampleTime;
  540. }
  541. void Engine::yieldWorkers() {
  542. }
  543. int64_t Engine::getFrame() {
  544. return internal->frame;
  545. }
  546. int64_t Engine::getBlock() {
  547. return internal->block;
  548. }
  549. int64_t Engine::getBlockFrame() {
  550. return internal->blockFrame;
  551. }
  552. double Engine::getBlockTime() {
  553. return internal->blockTime;
  554. }
  555. int Engine::getBlockFrames() {
  556. return internal->blockFrames;
  557. }
  558. double Engine::getBlockDuration() {
  559. return internal->blockFrames * internal->sampleTime;
  560. }
  561. double Engine::getMeterAverage() {
  562. #ifndef HEADLESS
  563. return internal->meterLastAverage;
  564. #else
  565. return 0.0;
  566. #endif
  567. }
  568. double Engine::getMeterMax() {
  569. #ifndef HEADLESS
  570. return internal->meterLastMax;
  571. #else
  572. return 0.0;
  573. #endif
  574. }
  575. size_t Engine::getNumModules() {
  576. return internal->modules.size() + internal->terminalModules.size();
  577. }
  578. size_t Engine::getModuleIds(int64_t* moduleIds, size_t len) {
  579. SharedLock<SharedMutex> lock(internal->mutex);
  580. size_t i = 0;
  581. for (Module* m : internal->modules) {
  582. if (i >= len)
  583. break;
  584. moduleIds[i++] = m->id;
  585. }
  586. for (TerminalModule* m : internal->terminalModules) {
  587. if (i >= len)
  588. break;
  589. moduleIds[i++] = m->id;
  590. }
  591. return i;
  592. }
  593. std::vector<int64_t> Engine::getModuleIds() {
  594. SharedLock<SharedMutex> lock(internal->mutex);
  595. std::vector<int64_t> moduleIds;
  596. moduleIds.reserve(getNumModules());
  597. for (Module* m : internal->modules) {
  598. moduleIds.push_back(m->id);
  599. }
  600. for (TerminalModule* tm : internal->terminalModules) {
  601. moduleIds.push_back(tm->id);
  602. }
  603. return moduleIds;
  604. }
  605. static TerminalModule* asTerminalModule(Module* const module) {
  606. const plugin::Model* const model = module->model;
  607. if (std::find(hostTerminalModels.begin(), hostTerminalModels.end(), model) != hostTerminalModels.end())
  608. return static_cast<TerminalModule*>(module);
  609. return nullptr;
  610. }
  611. void Engine::addModule(Module* module) {
  612. std::lock_guard<SharedMutex> lock(internal->mutex);
  613. DISTRHO_SAFE_ASSERT_RETURN(module != nullptr,);
  614. // Check that the module is not already added
  615. auto it = std::find(internal->modules.begin(), internal->modules.end(), module);
  616. DISTRHO_SAFE_ASSERT_RETURN(it == internal->modules.end(),);
  617. auto tit = std::find(internal->terminalModules.begin(), internal->terminalModules.end(), module);
  618. DISTRHO_SAFE_ASSERT_RETURN(tit == internal->terminalModules.end(),);
  619. // Set ID if unset or collides with an existing ID
  620. while (module->id < 0 || internal->modulesCache.find(module->id) != internal->modulesCache.end()) {
  621. // Randomly generate ID
  622. module->id = random::u64() % (1ull << 53);
  623. }
  624. // Add module
  625. if (TerminalModule* const terminalModule = asTerminalModule(module))
  626. internal->terminalModules.push_back(terminalModule);
  627. else
  628. internal->modules.push_back(module);
  629. internal->modulesCache[module->id] = module;
  630. // Dispatch AddEvent
  631. Module::AddEvent eAdd;
  632. module->onAdd(eAdd);
  633. // Dispatch SampleRateChangeEvent
  634. Module::SampleRateChangeEvent eSrc;
  635. eSrc.sampleRate = internal->sampleRate;
  636. eSrc.sampleTime = internal->sampleTime;
  637. module->onSampleRateChange(eSrc);
  638. // Update ParamHandles' module pointers
  639. for (ParamHandle* paramHandle : internal->paramHandles) {
  640. if (paramHandle->moduleId == module->id)
  641. paramHandle->module = module;
  642. }
  643. #if DEBUG_ORDERED_MODULES
  644. printf("New module: %s - %ld\n", module->model->getFullName().c_str(), module->id);
  645. #endif
  646. }
  647. void Engine::removeModule(Module* module) {
  648. std::lock_guard<SharedMutex> lock(internal->mutex);
  649. removeModule_NoLock(module);
  650. }
  651. static void removeModule_NoLock_common(Engine::Internal* internal, Module* module) {
  652. // Remove from widgets cache
  653. CardinalPluginModelHelper* const helper = dynamic_cast<CardinalPluginModelHelper*>(module->model);
  654. DISTRHO_SAFE_ASSERT_RETURN(helper != nullptr,);
  655. helper->removeCachedModuleWidget(module);
  656. // Dispatch RemoveEvent
  657. Module::RemoveEvent eRemove;
  658. module->onRemove(eRemove);
  659. // Update ParamHandles' module pointers
  660. for (ParamHandle* paramHandle : internal->paramHandles) {
  661. if (paramHandle->moduleId == module->id)
  662. paramHandle->module = NULL;
  663. }
  664. // If a param is being smoothed on this module, stop smoothing it immediately
  665. if (module == internal->smoothModule) {
  666. internal->smoothModule = NULL;
  667. }
  668. // Check that all cables are disconnected
  669. for (Cable* cable : internal->cables) {
  670. DISTRHO_SAFE_ASSERT(cable->inputModule != module);
  671. DISTRHO_SAFE_ASSERT(cable->outputModule != module);
  672. }
  673. // Update expanders of other modules
  674. for (Module* m : internal->modules) {
  675. if (m->leftExpander.module == module) {
  676. m->leftExpander.moduleId = -1;
  677. m->leftExpander.module = NULL;
  678. }
  679. if (m->rightExpander.module == module) {
  680. m->rightExpander.moduleId = -1;
  681. m->rightExpander.module = NULL;
  682. }
  683. }
  684. // Reset expanders
  685. module->leftExpander.moduleId = -1;
  686. module->leftExpander.module = NULL;
  687. module->rightExpander.moduleId = -1;
  688. module->rightExpander.module = NULL;
  689. // Remove module
  690. internal->modulesCache.erase(module->id);
  691. }
  692. void Engine::removeModule_NoLock(Module* module) {
  693. DISTRHO_SAFE_ASSERT_RETURN(module,);
  694. // Check that the module actually exists
  695. if (TerminalModule* const terminalModule = asTerminalModule(module)) {
  696. auto tit = std::find(internal->terminalModules.begin(), internal->terminalModules.end(), terminalModule);
  697. DISTRHO_SAFE_ASSERT_RETURN(tit != internal->terminalModules.end(),);
  698. removeModule_NoLock_common(internal, module);
  699. internal->terminalModules.erase(tit);
  700. }
  701. else {
  702. auto it = std::find(internal->modules.begin(), internal->modules.end(), module);
  703. DISTRHO_SAFE_ASSERT_RETURN(it != internal->modules.end(),);
  704. removeModule_NoLock_common(internal, module);
  705. internal->modules.erase(it);
  706. }
  707. }
  708. bool Engine::hasModule(Module* module) {
  709. SharedLock<SharedMutex> lock(internal->mutex);
  710. // TODO Performance could be improved by searching modulesCache, but more testing would be needed to make sure it's always valid.
  711. auto it = std::find(internal->modules.begin(), internal->modules.end(), module);
  712. auto tit = std::find(internal->terminalModules.begin(), internal->terminalModules.end(), module);
  713. return it != internal->modules.end() && tit != internal->terminalModules.end();
  714. }
  715. Module* Engine::getModule(int64_t moduleId) {
  716. SharedLock<SharedMutex> lock(internal->mutex);
  717. return getModule_NoLock(moduleId);
  718. }
  719. Module* Engine::getModule_NoLock(int64_t moduleId) {
  720. auto it = internal->modulesCache.find(moduleId);
  721. if (it == internal->modulesCache.end())
  722. return NULL;
  723. return it->second;
  724. }
  725. void Engine::resetModule(Module* module) {
  726. std::lock_guard<SharedMutex> lock(internal->mutex);
  727. DISTRHO_SAFE_ASSERT_RETURN(module,);
  728. Module::ResetEvent eReset;
  729. module->onReset(eReset);
  730. }
  731. void Engine::randomizeModule(Module* module) {
  732. std::lock_guard<SharedMutex> lock(internal->mutex);
  733. DISTRHO_SAFE_ASSERT_RETURN(module,);
  734. Module::RandomizeEvent eRandomize;
  735. module->onRandomize(eRandomize);
  736. }
  737. void Engine::bypassModule(Module* module, bool bypassed) {
  738. DISTRHO_SAFE_ASSERT_RETURN(module,);
  739. if (module->isBypassed() == bypassed)
  740. return;
  741. std::lock_guard<SharedMutex> lock(internal->mutex);
  742. // Clear outputs and set to 1 channel
  743. for (Output& output : module->outputs) {
  744. // This zeros all voltages, but the channel is set to 1 if connected
  745. output.setChannels(0);
  746. }
  747. // Set bypassed state
  748. module->setBypassed(bypassed);
  749. if (bypassed) {
  750. // Dispatch BypassEvent
  751. Module::BypassEvent eBypass;
  752. module->onBypass(eBypass);
  753. }
  754. else {
  755. // Dispatch UnBypassEvent
  756. Module::UnBypassEvent eUnBypass;
  757. module->onUnBypass(eUnBypass);
  758. }
  759. }
  760. json_t* Engine::moduleToJson(Module* module) {
  761. SharedLock<SharedMutex> lock(internal->mutex);
  762. return module->toJson();
  763. }
  764. void Engine::moduleFromJson(Module* module, json_t* rootJ) {
  765. std::lock_guard<SharedMutex> lock(internal->mutex);
  766. module->fromJson(rootJ);
  767. }
  768. void Engine::prepareSaveModule(Module* module) {
  769. SharedLock<SharedMutex> lock(internal->mutex);
  770. Module::SaveEvent e;
  771. module->onSave(e);
  772. }
  773. void Engine::prepareSave() {
  774. if (internal->aboutToClose)
  775. return;
  776. SharedLock<SharedMutex> lock(internal->mutex);
  777. for (Module* module : internal->modules) {
  778. Module::SaveEvent e;
  779. module->onSave(e);
  780. }
  781. for (TerminalModule* terminalModule : internal->terminalModules) {
  782. Module::SaveEvent e;
  783. terminalModule->onSave(e);
  784. }
  785. }
  786. size_t Engine::getNumCables() {
  787. return internal->cables.size();
  788. }
  789. size_t Engine::getCableIds(int64_t* cableIds, size_t len) {
  790. SharedLock<SharedMutex> lock(internal->mutex);
  791. size_t i = 0;
  792. for (Cable* c : internal->cables) {
  793. if (i >= len)
  794. break;
  795. cableIds[i] = c->id;
  796. i++;
  797. }
  798. return i;
  799. }
  800. std::vector<int64_t> Engine::getCableIds() {
  801. SharedLock<SharedMutex> lock(internal->mutex);
  802. std::vector<int64_t> cableIds;
  803. cableIds.reserve(internal->cables.size());
  804. for (Cable* c : internal->cables) {
  805. cableIds.push_back(c->id);
  806. }
  807. return cableIds;
  808. }
  809. void Engine::addCable(Cable* cable) {
  810. std::lock_guard<SharedMutex> lock(internal->mutex);
  811. DISTRHO_SAFE_ASSERT_RETURN(cable,);
  812. // Check cable properties
  813. DISTRHO_SAFE_ASSERT_RETURN(cable->inputModule,);
  814. DISTRHO_SAFE_ASSERT_RETURN(cable->outputModule,);
  815. bool outputWasConnected = false;
  816. for (Cable* cable2 : internal->cables) {
  817. // Check that the cable is not already added
  818. DISTRHO_SAFE_ASSERT_RETURN(cable2 != cable,);
  819. // Check that the input is not already used by another cable
  820. DISTRHO_SAFE_ASSERT_RETURN(!(cable2->inputModule == cable->inputModule && cable2->inputId == cable->inputId),);
  821. // Get connected status of output, to decide whether we need to call a PortChangeEvent.
  822. // It's best to not trust `cable->outputModule->outputs[cable->outputId]->isConnected()`
  823. if (cable2->outputModule == cable->outputModule && cable2->outputId == cable->outputId)
  824. outputWasConnected = true;
  825. }
  826. // Set ID if unset or collides with an existing ID
  827. while (cable->id < 0 || internal->cablesCache.find(cable->id) != internal->cablesCache.end()) {
  828. // Randomly generate ID
  829. cable->id = random::u64() % (1ull << 53);
  830. }
  831. // Add the cable
  832. internal->cables.push_back(cable);
  833. internal->cablesCache[cable->id] = cable;
  834. // Add the cable's zero-latency shortcut
  835. cable->outputModule->outputs[cable->outputId].cables.push_back(cable);
  836. Engine_updateConnected(this);
  837. // Dispatch input port event
  838. {
  839. Module::PortChangeEvent e;
  840. e.connecting = true;
  841. e.type = Port::INPUT;
  842. e.portId = cable->inputId;
  843. cable->inputModule->onPortChange(e);
  844. }
  845. // Dispatch output port event if its state went from disconnected to connected.
  846. if (!outputWasConnected) {
  847. Module::PortChangeEvent e;
  848. e.connecting = true;
  849. e.type = Port::OUTPUT;
  850. e.portId = cable->outputId;
  851. cable->outputModule->onPortChange(e);
  852. }
  853. }
  854. void Engine::removeCable(Cable* cable) {
  855. std::lock_guard<SharedMutex> lock(internal->mutex);
  856. removeCable_NoLock(cable);
  857. }
  858. void Engine::removeCable_NoLock(Cable* cable) {
  859. DISTRHO_SAFE_ASSERT_RETURN(cable,);
  860. // Check that the cable is already added
  861. auto it = std::find(internal->cables.begin(), internal->cables.end(), cable);
  862. DISTRHO_SAFE_ASSERT_RETURN(it != internal->cables.end(),);
  863. // Remove the cable's zero-latency shortcut
  864. cable->outputModule->outputs[cable->outputId].cables.remove(cable);
  865. // Remove the cable
  866. internal->cablesCache.erase(cable->id);
  867. internal->cables.erase(it);
  868. Engine_updateConnected(this);
  869. bool outputIsConnected = false;
  870. for (Cable* cable2 : internal->cables) {
  871. // Get connected status of output, to decide whether we need to call a PortChangeEvent.
  872. // It's best to not trust `cable->outputModule->outputs[cable->outputId]->isConnected()`
  873. if (cable2->outputModule == cable->outputModule && cable2->outputId == cable->outputId)
  874. outputIsConnected = true;
  875. }
  876. // Dispatch input port event
  877. {
  878. Module::PortChangeEvent e;
  879. e.connecting = false;
  880. e.type = Port::INPUT;
  881. e.portId = cable->inputId;
  882. cable->inputModule->onPortChange(e);
  883. }
  884. // Dispatch output port event if its state went from connected to disconnected.
  885. if (!outputIsConnected) {
  886. Module::PortChangeEvent e;
  887. e.connecting = false;
  888. e.type = Port::OUTPUT;
  889. e.portId = cable->outputId;
  890. cable->outputModule->onPortChange(e);
  891. }
  892. }
  893. bool Engine::hasCable(Cable* cable) {
  894. SharedLock<SharedMutex> lock(internal->mutex);
  895. // TODO Performance could be improved by searching cablesCache, but more testing would be needed to make sure it's always valid.
  896. auto it = std::find(internal->cables.begin(), internal->cables.end(), cable);
  897. return it != internal->cables.end();
  898. }
  899. Cable* Engine::getCable(int64_t cableId) {
  900. SharedLock<SharedMutex> lock(internal->mutex);
  901. auto it = internal->cablesCache.find(cableId);
  902. if (it == internal->cablesCache.end())
  903. return NULL;
  904. return it->second;
  905. }
  906. void Engine::setParamValue(Module* module, int paramId, float value) {
  907. // If param is being smoothed, cancel smoothing.
  908. if (internal->smoothModule == module && internal->smoothParamId == paramId) {
  909. internal->smoothModule = NULL;
  910. internal->smoothParamId = 0;
  911. }
  912. if (internal->remoteDetails != nullptr) {
  913. sendParamChangeToRemote(internal->remoteDetails, module->id, paramId, value);
  914. }
  915. module->params[paramId].setValue(value);
  916. }
  917. float Engine::getParamValue(Module* module, int paramId) {
  918. return module->params[paramId].getValue();
  919. }
  920. void Engine::setParamSmoothValue(Module* module, int paramId, float value) {
  921. // If another param is being smoothed, jump value
  922. if (internal->smoothModule && !(internal->smoothModule == module && internal->smoothParamId == paramId)) {
  923. internal->smoothModule->params[internal->smoothParamId].setValue(internal->smoothValue);
  924. }
  925. internal->smoothParamId = paramId;
  926. internal->smoothValue = value;
  927. // Set this last so the above values are valid as soon as it is set
  928. internal->smoothModule = module;
  929. }
  930. float Engine::getParamSmoothValue(Module* module, int paramId) {
  931. if (internal->smoothModule == module && internal->smoothParamId == paramId)
  932. return internal->smoothValue;
  933. return module->params[paramId].getValue();
  934. }
  935. void Engine::addParamHandle(ParamHandle* paramHandle) {
  936. std::lock_guard<SharedMutex> lock(internal->mutex);
  937. // New ParamHandles must be blank.
  938. // This means we don't have to refresh the cache.
  939. DISTRHO_SAFE_ASSERT_RETURN(paramHandle->moduleId < 0,);
  940. // Check that the ParamHandle is not already added
  941. auto it = internal->paramHandles.find(paramHandle);
  942. DISTRHO_SAFE_ASSERT_RETURN(it == internal->paramHandles.end(),);
  943. // Add it
  944. internal->paramHandles.insert(paramHandle);
  945. // No need to refresh the cache because the moduleId is not set.
  946. }
  947. void Engine::removeParamHandle(ParamHandle* paramHandle) {
  948. std::lock_guard<SharedMutex> lock(internal->mutex);
  949. removeParamHandle_NoLock(paramHandle);
  950. }
  951. void Engine::removeParamHandle_NoLock(ParamHandle* paramHandle) {
  952. // Check that the ParamHandle is already added
  953. auto it = internal->paramHandles.find(paramHandle);
  954. DISTRHO_SAFE_ASSERT_RETURN(it != internal->paramHandles.end(),);
  955. // Remove it
  956. paramHandle->module = NULL;
  957. internal->paramHandles.erase(it);
  958. Engine_refreshParamHandleCache(this);
  959. }
  960. ParamHandle* Engine::getParamHandle(int64_t moduleId, int paramId) {
  961. SharedLock<SharedMutex> lock(internal->mutex);
  962. return getParamHandle_NoLock(moduleId, paramId);
  963. }
  964. ParamHandle* Engine::getParamHandle_NoLock(int64_t moduleId, int paramId) {
  965. auto it = internal->paramHandlesCache.find(std::make_tuple(moduleId, paramId));
  966. if (it == internal->paramHandlesCache.end())
  967. return NULL;
  968. return it->second;
  969. }
  970. ParamHandle* Engine::getParamHandle(Module* module, int paramId) {
  971. return getParamHandle(module->id, paramId);
  972. }
  973. void Engine::updateParamHandle(ParamHandle* paramHandle, int64_t moduleId, int paramId, bool overwrite) {
  974. std::lock_guard<SharedMutex> lock(internal->mutex);
  975. updateParamHandle_NoLock(paramHandle, moduleId, paramId, overwrite);
  976. }
  977. void Engine::updateParamHandle_NoLock(ParamHandle* paramHandle, int64_t moduleId, int paramId, bool overwrite) {
  978. // Check that it exists
  979. auto it = internal->paramHandles.find(paramHandle);
  980. DISTRHO_SAFE_ASSERT_RETURN(it != internal->paramHandles.end(),);
  981. // Set IDs
  982. paramHandle->moduleId = moduleId;
  983. paramHandle->paramId = paramId;
  984. paramHandle->module = NULL;
  985. // At this point, the ParamHandle cache might be invalid.
  986. if (paramHandle->moduleId >= 0) {
  987. // Replace old ParamHandle, or reset the current ParamHandle
  988. ParamHandle* oldParamHandle = getParamHandle_NoLock(moduleId, paramId);
  989. if (oldParamHandle) {
  990. if (overwrite) {
  991. oldParamHandle->moduleId = -1;
  992. oldParamHandle->paramId = 0;
  993. oldParamHandle->module = NULL;
  994. }
  995. else {
  996. paramHandle->moduleId = -1;
  997. paramHandle->paramId = 0;
  998. paramHandle->module = NULL;
  999. }
  1000. }
  1001. }
  1002. // Set module pointer if the above block didn't reset it
  1003. if (paramHandle->moduleId >= 0) {
  1004. paramHandle->module = getModule_NoLock(paramHandle->moduleId);
  1005. }
  1006. Engine_refreshParamHandleCache(this);
  1007. }
  1008. json_t* Engine::toJson() {
  1009. SharedLock<SharedMutex> lock(internal->mutex);
  1010. json_t* rootJ = json_object();
  1011. // modules
  1012. json_t* modulesJ = json_array();
  1013. for (Module* module : internal->modules) {
  1014. json_t* moduleJ = module->toJson();
  1015. json_array_append_new(modulesJ, moduleJ);
  1016. }
  1017. for (TerminalModule* terminalModule : internal->terminalModules) {
  1018. json_t* terminalModuleJ = terminalModule->toJson();
  1019. json_array_append_new(modulesJ, terminalModuleJ);
  1020. }
  1021. json_object_set_new(rootJ, "modules", modulesJ);
  1022. // cables
  1023. json_t* cablesJ = json_array();
  1024. for (Cable* cable : internal->cables) {
  1025. json_t* cableJ = cable->toJson();
  1026. json_array_append_new(cablesJ, cableJ);
  1027. }
  1028. json_object_set_new(rootJ, "cables", cablesJ);
  1029. return rootJ;
  1030. }
  1031. void Engine::fromJson(json_t* rootJ) {
  1032. // Don't write-lock the entire method because most of it doesn't need it.
  1033. // Write-locks
  1034. clear();
  1035. // modules
  1036. json_t* modulesJ = json_object_get(rootJ, "modules");
  1037. if (!modulesJ)
  1038. return;
  1039. size_t moduleIndex;
  1040. json_t* moduleJ;
  1041. json_array_foreach(modulesJ, moduleIndex, moduleJ) {
  1042. // Get model
  1043. plugin::Model* model;
  1044. try {
  1045. model = plugin::modelFromJson(moduleJ);
  1046. }
  1047. catch (Exception& e) {
  1048. WARN("Cannot load model: %s", e.what());
  1049. // APP->patch->log(e.what());
  1050. continue;
  1051. }
  1052. // Create module
  1053. Module* const module = model->createModule();
  1054. DISTRHO_SAFE_ASSERT_CONTINUE(module != nullptr);
  1055. // Create the widget too, needed by a few modules
  1056. CardinalPluginModelHelper* const helper = dynamic_cast<CardinalPluginModelHelper*>(model);
  1057. DISTRHO_SAFE_ASSERT_CONTINUE(helper != nullptr);
  1058. app::ModuleWidget* const moduleWidget = helper->createModuleWidgetFromEngineLoad(module);
  1059. DISTRHO_SAFE_ASSERT_CONTINUE(moduleWidget != nullptr);
  1060. try {
  1061. // This doesn't need a lock because the Module is not added to the Engine yet.
  1062. module->fromJson(moduleJ);
  1063. // Before 1.0, the module ID was the index in the "modules" array
  1064. if (module->id < 0) {
  1065. module->id = moduleIndex;
  1066. }
  1067. // Write-locks
  1068. addModule(module);
  1069. }
  1070. catch (Exception& e) {
  1071. WARN("Cannot load module: %s", e.what());
  1072. // APP->patch->log(e.what());
  1073. helper->removeCachedModuleWidget(module);
  1074. delete module;
  1075. continue;
  1076. }
  1077. }
  1078. // cables
  1079. json_t* cablesJ = json_object_get(rootJ, "cables");
  1080. // Before 1.0, cables were called wires
  1081. if (!cablesJ)
  1082. cablesJ = json_object_get(rootJ, "wires");
  1083. if (!cablesJ)
  1084. return;
  1085. size_t cableIndex;
  1086. json_t* cableJ;
  1087. json_array_foreach(cablesJ, cableIndex, cableJ) {
  1088. // cable
  1089. Cable* cable = new Cable;
  1090. try {
  1091. cable->fromJson(cableJ);
  1092. // Before 1.0, the cable ID was the index in the "cables" array
  1093. if (cable->id < 0) {
  1094. cable->id = cableIndex;
  1095. }
  1096. // Write-locks
  1097. addCable(cable);
  1098. }
  1099. catch (Exception& e) {
  1100. WARN("Cannot load cable: %s", e.what());
  1101. delete cable;
  1102. // Don't log exceptions because missing modules create unnecessary complaining when cables try to connect to them.
  1103. continue;
  1104. }
  1105. }
  1106. }
  1107. void Engine::startFallbackThread() {
  1108. }
  1109. void Engine_setAboutToClose(Engine* const engine) {
  1110. engine->internal->aboutToClose = true;
  1111. }
  1112. void Engine_setRemoteDetails(Engine* const engine, remoteUtils::RemoteDetails* const remoteDetails) {
  1113. engine->internal->remoteDetails = remoteDetails;
  1114. }
  1115. } // namespace engine
  1116. } // namespace rack