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.

1029 lines
26KB

  1. #include <engine/Engine.hpp>
  2. #include <settings.hpp>
  3. #include <system.hpp>
  4. #include <random.hpp>
  5. #include <app.hpp>
  6. #include <patch.hpp>
  7. #include <plugin.hpp>
  8. #include <algorithm>
  9. #include <chrono>
  10. #include <thread>
  11. #include <condition_variable>
  12. #include <mutex>
  13. #include <atomic>
  14. #include <tuple>
  15. #include <pmmintrin.h>
  16. namespace rack {
  17. namespace engine {
  18. static void initMXCSR() {
  19. // Set CPU to flush-to-zero (FTZ) and denormals-are-zero (DAZ) mode
  20. // https://software.intel.com/en-us/node/682949
  21. _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
  22. _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
  23. // Reset other flags
  24. _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
  25. }
  26. struct Barrier {
  27. std::mutex mutex;
  28. std::condition_variable cv;
  29. int count = 0;
  30. int total = 0;
  31. void wait() {
  32. // Waiting on one thread is trivial.
  33. if (total <= 1)
  34. return;
  35. std::unique_lock<std::mutex> lock(mutex);
  36. int id = ++count;
  37. if (id == total) {
  38. count = 0;
  39. cv.notify_all();
  40. }
  41. else {
  42. cv.wait(lock);
  43. }
  44. }
  45. };
  46. struct SpinBarrier {
  47. std::atomic<int> count{0};
  48. int total = 0;
  49. void wait() {
  50. int id = ++count;
  51. if (id == total) {
  52. count = 0;
  53. }
  54. else {
  55. while (count != 0) {
  56. _mm_pause();
  57. }
  58. }
  59. }
  60. };
  61. /** Spinlocks until all `total` threads are waiting.
  62. If `yield` is set to true at any time, all threads will switch to waiting on a mutex instead.
  63. All threads must return before beginning a new phase. Alternating between two barriers solves this problem.
  64. */
  65. struct HybridBarrier {
  66. std::atomic<int> count {0};
  67. int total = 0;
  68. std::mutex mutex;
  69. std::condition_variable cv;
  70. std::atomic<bool> yield {false};
  71. void wait() {
  72. int id = ++count;
  73. // End and reset phase if this is the last thread
  74. if (id == total) {
  75. count = 0;
  76. if (yield) {
  77. std::unique_lock<std::mutex> lock(mutex);
  78. cv.notify_all();
  79. yield = false;
  80. }
  81. return;
  82. }
  83. // Spinlock
  84. while (!yield) {
  85. if (count == 0)
  86. return;
  87. _mm_pause();
  88. }
  89. // Wait on mutex
  90. {
  91. std::unique_lock<std::mutex> lock(mutex);
  92. cv.wait(lock, [&] {
  93. return count == 0;
  94. });
  95. }
  96. }
  97. };
  98. struct EngineWorker {
  99. Engine* engine;
  100. int id;
  101. std::thread thread;
  102. bool running = false;
  103. void start() {
  104. assert(!running);
  105. running = true;
  106. thread = std::thread([&] {
  107. run();
  108. });
  109. }
  110. void requestStop() {
  111. running = false;
  112. }
  113. void join() {
  114. assert(thread.joinable());
  115. thread.join();
  116. }
  117. void run();
  118. };
  119. struct Engine::Internal {
  120. std::vector<Module*> modules;
  121. std::vector<Cable*> cables;
  122. std::set<ParamHandle*> paramHandles;
  123. std::map<std::tuple<int, int>, ParamHandle*> paramHandleCache;
  124. bool paused = false;
  125. float sampleRate = 0.f;
  126. float sampleTime = 0.f;
  127. uint64_t frame = 0;
  128. Module* primaryModule = NULL;
  129. int nextModuleId = 0;
  130. int nextCableId = 0;
  131. // Parameter smoothing
  132. Module* smoothModule = NULL;
  133. int smoothParamId = 0;
  134. float smoothValue = 0.f;
  135. std::recursive_mutex mutex;
  136. int threadCount = 0;
  137. std::vector<EngineWorker> workers;
  138. HybridBarrier engineBarrier;
  139. HybridBarrier workerBarrier;
  140. std::atomic<int> workerModuleIndex;
  141. };
  142. static void Port_step(Port* that, float deltaTime) {
  143. // Set plug lights
  144. if (that->channels == 0) {
  145. that->plugLights[0].setBrightness(0.f);
  146. that->plugLights[1].setBrightness(0.f);
  147. that->plugLights[2].setBrightness(0.f);
  148. }
  149. else if (that->channels == 1) {
  150. float v = that->getVoltage() / 10.f;
  151. that->plugLights[0].setSmoothBrightness(v, deltaTime);
  152. that->plugLights[1].setSmoothBrightness(-v, deltaTime);
  153. that->plugLights[2].setBrightness(0.f);
  154. }
  155. else {
  156. float v2 = 0.f;
  157. for (int c = 0; c < that->channels; c++) {
  158. v2 += std::pow(that->getVoltage(c), 2);
  159. }
  160. float v = std::sqrt(v2) / 10.f;
  161. that->plugLights[0].setBrightness(0.f);
  162. that->plugLights[1].setBrightness(0.f);
  163. that->plugLights[2].setSmoothBrightness(v, deltaTime);
  164. }
  165. }
  166. static void Engine_stepModulesWorker(Engine* that, int threadId) {
  167. Engine::Internal* internal = that->internal;
  168. // int threadCount = internal->threadCount;
  169. int modulesLen = internal->modules.size();
  170. Module::ProcessArgs processArgs;
  171. processArgs.sampleRate = internal->sampleRate;
  172. processArgs.sampleTime = internal->sampleTime;
  173. bool cpuMeter = settings::cpuMeter;
  174. // Step each module
  175. while (true) {
  176. // Choose next module
  177. // First-come-first serve module-to-thread allocation algorithm
  178. int i = internal->workerModuleIndex++;
  179. if (i >= modulesLen)
  180. break;
  181. Module* module = internal->modules[i];
  182. // Start CPU timer
  183. using time_point = std::chrono::time_point<std::chrono::high_resolution_clock>;
  184. time_point beginTime;
  185. if (cpuMeter) {
  186. beginTime = std::chrono::high_resolution_clock::now();
  187. }
  188. // Step module
  189. if (!module->bypassed())
  190. module->process(processArgs);
  191. else
  192. module->processBypass(processArgs);
  193. // Stop CPU timer
  194. if (cpuMeter) {
  195. time_point endTime = std::chrono::high_resolution_clock::now();
  196. float duration = std::chrono::duration<float>(endTime - beginTime).count();
  197. // Smooth CPU time
  198. const float cpuTau = 2.f /* seconds */;
  199. module->cpuTime() += (duration - module->cpuTime()) * processArgs.sampleTime / cpuTau;
  200. }
  201. // Iterate ports to step plug lights
  202. const int portDivider = 8;
  203. if (internal->frame % portDivider == 0) {
  204. float portTime = processArgs.sampleTime * portDivider;
  205. for (Input& input : module->inputs) {
  206. Port_step(&input, portTime);
  207. }
  208. for (Output& output : module->outputs) {
  209. Port_step(&output, portTime);
  210. }
  211. }
  212. }
  213. }
  214. static void Cable_step(Cable* that) {
  215. Output* output = &that->outputModule->outputs[that->outputId];
  216. Input* input = &that->inputModule->inputs[that->inputId];
  217. // Match number of polyphonic channels to output port
  218. int channels = output->channels;
  219. // Copy all voltages from output to input
  220. for (int c = 0; c < channels; c++) {
  221. float v = output->voltages[c];
  222. // Set 0V if infinite or NaN
  223. if (!std::isfinite(v))
  224. v = 0.f;
  225. input->voltages[c] = v;
  226. }
  227. // Set higher channel voltages to 0
  228. for (int c = channels; c < input->channels; c++) {
  229. input->voltages[c] = 0.f;
  230. }
  231. input->channels = channels;
  232. }
  233. static void Engine_stepModules(Engine* that) {
  234. Engine::Internal* internal = that->internal;
  235. // Param smoothing
  236. Module* smoothModule = internal->smoothModule;
  237. int smoothParamId = internal->smoothParamId;
  238. float smoothValue = internal->smoothValue;
  239. if (smoothModule) {
  240. Param* param = &smoothModule->params[smoothParamId];
  241. float value = param->value;
  242. // Decay rate is 1 graphics frame
  243. const float smoothLambda = 60.f;
  244. float newValue = value + (smoothValue - value) * smoothLambda * internal->sampleTime;
  245. if (value == newValue) {
  246. // Snap to actual smooth value if the value doesn't change enough (due to the granularity of floats)
  247. param->setValue(smoothValue);
  248. internal->smoothModule = NULL;
  249. internal->smoothParamId = 0;
  250. }
  251. else {
  252. param->value = newValue;
  253. }
  254. }
  255. // Step cables
  256. for (Cable* cable : that->internal->cables) {
  257. Cable_step(cable);
  258. }
  259. // Flip messages for each module
  260. for (Module* module : that->internal->modules) {
  261. if (module->leftExpander.messageFlipRequested) {
  262. std::swap(module->leftExpander.producerMessage, module->leftExpander.consumerMessage);
  263. module->leftExpander.messageFlipRequested = false;
  264. }
  265. if (module->rightExpander.messageFlipRequested) {
  266. std::swap(module->rightExpander.producerMessage, module->rightExpander.consumerMessage);
  267. module->rightExpander.messageFlipRequested = false;
  268. }
  269. }
  270. // Step modules along with workers
  271. internal->workerModuleIndex = 0;
  272. internal->engineBarrier.wait();
  273. Engine_stepModulesWorker(that, 0);
  274. internal->workerBarrier.wait();
  275. internal->frame++;
  276. }
  277. static void Engine_updateExpander(Engine* that, Module::Expander* expander) {
  278. if (expander->moduleId >= 0) {
  279. if (!expander->module || expander->module->id != expander->moduleId) {
  280. expander->module = that->getModule(expander->moduleId);
  281. }
  282. }
  283. else {
  284. if (expander->module) {
  285. expander->module = NULL;
  286. }
  287. }
  288. }
  289. static void Engine_relaunchWorkers(Engine* that, int threadCount) {
  290. Engine::Internal* internal = that->internal;
  291. if (internal->threadCount > 0) {
  292. // Stop engine workers
  293. for (EngineWorker& worker : internal->workers) {
  294. worker.requestStop();
  295. }
  296. internal->engineBarrier.wait();
  297. // Join and destroy engine workers
  298. for (EngineWorker& worker : internal->workers) {
  299. worker.join();
  300. }
  301. internal->workers.resize(0);
  302. }
  303. // Configure engine
  304. internal->threadCount = threadCount;
  305. // Set barrier counts
  306. internal->engineBarrier.total = threadCount;
  307. internal->workerBarrier.total = threadCount;
  308. if (threadCount > 0) {
  309. // Create and start engine workers
  310. internal->workers.resize(threadCount - 1);
  311. for (int id = 1; id < threadCount; id++) {
  312. EngineWorker& worker = internal->workers[id - 1];
  313. worker.id = id;
  314. worker.engine = that;
  315. worker.start();
  316. }
  317. }
  318. }
  319. Engine::Engine() {
  320. internal = new Internal;
  321. internal->sampleRate = 44100.f;
  322. internal->sampleTime = 1 / internal->sampleRate;
  323. }
  324. Engine::~Engine() {
  325. Engine_relaunchWorkers(this, 0);
  326. clear();
  327. // Make sure there are no cables or modules in the rack on destruction.
  328. // If this happens, a module must have failed to remove itself before the RackWidget was destroyed.
  329. assert(internal->cables.empty());
  330. assert(internal->modules.empty());
  331. assert(internal->paramHandles.empty());
  332. assert(internal->paramHandleCache.empty());
  333. delete internal;
  334. }
  335. void Engine::clear() {
  336. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  337. // Copy lists because we'll be removing while iterating
  338. std::set<ParamHandle*> paramHandles = internal->paramHandles;
  339. for (ParamHandle* paramHandle : paramHandles) {
  340. removeParamHandle(paramHandle);
  341. }
  342. std::vector<Cable*> cables = internal->cables;
  343. for (Cable* cable : cables) {
  344. removeCable(cable);
  345. }
  346. std::vector<Module*> modules = internal->modules;
  347. for (Module* module : modules) {
  348. removeModule(module);
  349. }
  350. // Reset engine state
  351. internal->nextModuleId = 0;
  352. internal->nextCableId = 0;
  353. }
  354. void Engine::step(int frames) {
  355. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  356. // Configure thread
  357. initMXCSR();
  358. random::init();
  359. // Set sample rate
  360. if (internal->sampleRate != settings::sampleRate) {
  361. internal->sampleRate = settings::sampleRate;
  362. internal->sampleTime = 1 / internal->sampleRate;
  363. Module::SampleRateChangeEvent e;
  364. e.sampleRate = internal->sampleRate;
  365. e.sampleTime = internal->sampleTime;
  366. for (Module* module : internal->modules) {
  367. module->onSampleRateChange(e);
  368. }
  369. }
  370. if (!internal->paused) {
  371. // Launch workers
  372. if (internal->threadCount != settings::threadCount) {
  373. Engine_relaunchWorkers(this, settings::threadCount);
  374. }
  375. // Update expander pointers
  376. for (Module* module : internal->modules) {
  377. Engine_updateExpander(this, &module->leftExpander);
  378. Engine_updateExpander(this, &module->rightExpander);
  379. }
  380. // Step modules
  381. for (int i = 0; i < frames; i++) {
  382. Engine_stepModules(this);
  383. }
  384. }
  385. else {
  386. // Stop workers while paused
  387. if (internal->threadCount != 1) {
  388. Engine_relaunchWorkers(this, 1);
  389. }
  390. }
  391. yieldWorkers();
  392. }
  393. void Engine::setPrimaryModule(Module* module) {
  394. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  395. internal->primaryModule = module;
  396. }
  397. Module* Engine::getPrimaryModule() {
  398. // No lock, for performance
  399. return internal->primaryModule;
  400. }
  401. void Engine::setPaused(bool paused) {
  402. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  403. internal->paused = paused;
  404. }
  405. bool Engine::isPaused() {
  406. // No lock, for performance
  407. return internal->paused;
  408. }
  409. float Engine::getSampleRate() {
  410. // No lock, for performance
  411. return internal->sampleRate;
  412. }
  413. float Engine::getSampleTime() {
  414. // No lock, for performance
  415. return internal->sampleTime;
  416. }
  417. void Engine::yieldWorkers() {
  418. internal->workerBarrier.yield = true;
  419. }
  420. uint64_t Engine::getFrame() {
  421. // No lock, for performance
  422. return internal->frame;
  423. }
  424. void Engine::addModule(Module* module) {
  425. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  426. assert(module);
  427. // Check that the module is not already added
  428. auto it = std::find(internal->modules.begin(), internal->modules.end(), module);
  429. assert(it == internal->modules.end());
  430. // Set ID
  431. if (module->id < 0) {
  432. // Automatically assign ID
  433. module->id = internal->nextModuleId++;
  434. }
  435. else {
  436. // Manual ID
  437. // Check that the ID is not already taken
  438. for (Module* m : internal->modules) {
  439. assert(module->id != m->id);
  440. }
  441. if (module->id >= internal->nextModuleId) {
  442. internal->nextModuleId = module->id + 1;
  443. }
  444. }
  445. // Add module
  446. internal->modules.push_back(module);
  447. // Trigger Add event
  448. Module::AddEvent eAdd;
  449. module->onAdd(eAdd);
  450. // Update ParamHandles' module pointers
  451. for (ParamHandle* paramHandle : internal->paramHandles) {
  452. if (paramHandle->moduleId == module->id)
  453. paramHandle->module = module;
  454. }
  455. // DEBUG("Added module %d to engine", module->id);
  456. }
  457. void Engine::removeModule(Module* module) {
  458. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  459. assert(module);
  460. // Check that the module actually exists
  461. auto it = std::find(internal->modules.begin(), internal->modules.end(), module);
  462. assert(it != internal->modules.end());
  463. // If a param is being smoothed on this module, stop smoothing it immediately
  464. if (module == internal->smoothModule) {
  465. internal->smoothModule = NULL;
  466. }
  467. // Check that all cables are disconnected
  468. for (Cable* cable : internal->cables) {
  469. assert(cable->inputModule != module);
  470. assert(cable->outputModule != module);
  471. }
  472. // Update ParamHandles' module pointers
  473. for (ParamHandle* paramHandle : internal->paramHandles) {
  474. if (paramHandle->moduleId == module->id)
  475. paramHandle->module = NULL;
  476. }
  477. // Update expander pointers
  478. for (Module* m : internal->modules) {
  479. if (m->leftExpander.module == module) {
  480. m->leftExpander.moduleId = -1;
  481. m->leftExpander.module = NULL;
  482. }
  483. if (m->rightExpander.module == module) {
  484. m->rightExpander.moduleId = -1;
  485. m->rightExpander.module = NULL;
  486. }
  487. }
  488. // Trigger Remove event
  489. Module::RemoveEvent eRemove;
  490. module->onRemove(eRemove);
  491. // Unset primary module
  492. if (internal->primaryModule == module)
  493. internal->primaryModule = NULL;
  494. // Remove module
  495. internal->modules.erase(it);
  496. // DEBUG("Removed module %d to engine", module->id);
  497. }
  498. Module* Engine::getModule(int moduleId) {
  499. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  500. // Find module
  501. for (Module* module : internal->modules) {
  502. if (module->id == moduleId)
  503. return module;
  504. }
  505. return NULL;
  506. }
  507. void Engine::resetModule(Module* module) {
  508. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  509. assert(module);
  510. Module::ResetEvent eReset;
  511. module->onReset(eReset);
  512. }
  513. void Engine::randomizeModule(Module* module) {
  514. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  515. assert(module);
  516. Module::RandomizeEvent eRandomize;
  517. module->onRandomize(eRandomize);
  518. }
  519. void Engine::bypassModule(Module* module, bool bypassed) {
  520. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  521. assert(module);
  522. if (module->bypassed() == bypassed)
  523. return;
  524. // Clear outputs and set to 1 channel
  525. for (Output& output : module->outputs) {
  526. // This zeros all voltages, but the channel is set to 1 if connected
  527. output.setChannels(0);
  528. }
  529. module->bypassed() = bypassed;
  530. // Trigger event
  531. if (bypassed) {
  532. Module::BypassEvent eBypass;
  533. module->onBypass(eBypass);
  534. }
  535. else {
  536. Module::UnBypassEvent eUnBypass;
  537. module->onUnBypass(eUnBypass);
  538. }
  539. }
  540. static void Port_setDisconnected(Port* that) {
  541. that->channels = 0;
  542. for (int c = 0; c < PORT_MAX_CHANNELS; c++) {
  543. that->voltages[c] = 0.f;
  544. }
  545. }
  546. static void Port_setConnected(Port* that) {
  547. if (that->channels > 0)
  548. return;
  549. that->channels = 1;
  550. }
  551. static void Engine_updateConnected(Engine* that) {
  552. // Find disconnected ports
  553. std::set<Port*> disconnectedPorts;
  554. for (Module* module : that->internal->modules) {
  555. for (Input& input : module->inputs) {
  556. disconnectedPorts.insert(&input);
  557. }
  558. for (Output& output : module->outputs) {
  559. disconnectedPorts.insert(&output);
  560. }
  561. }
  562. for (Cable* cable : that->internal->cables) {
  563. // Connect input
  564. Input& input = cable->inputModule->inputs[cable->inputId];
  565. auto inputIt = disconnectedPorts.find(&input);
  566. if (inputIt != disconnectedPorts.end())
  567. disconnectedPorts.erase(inputIt);
  568. Port_setConnected(&input);
  569. // Connect output
  570. Output& output = cable->outputModule->outputs[cable->outputId];
  571. auto outputIt = disconnectedPorts.find(&output);
  572. if (outputIt != disconnectedPorts.end())
  573. disconnectedPorts.erase(outputIt);
  574. Port_setConnected(&output);
  575. }
  576. // Disconnect ports that have no cable
  577. for (Port* port : disconnectedPorts) {
  578. Port_setDisconnected(port);
  579. }
  580. }
  581. void Engine::addCable(Cable* cable) {
  582. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  583. assert(cable);
  584. // Check cable properties
  585. assert(cable->inputModule);
  586. assert(cable->outputModule);
  587. bool outputWasConnected = false;
  588. for (Cable* cable2 : internal->cables) {
  589. // Check that the cable is not already added
  590. assert(cable2 != cable);
  591. // Check that the input is not already used by another cable
  592. assert(!(cable2->inputModule == cable->inputModule && cable2->inputId == cable->inputId));
  593. // Get connected status of output, to decide whether we need to call a PortChangeEvent.
  594. // It's best to not trust `cable->outputModule->outputs[cable->outputId]->isConnected()`
  595. if (cable2->outputModule == cable->outputModule && cable2->outputId == cable->outputId)
  596. outputWasConnected = true;
  597. }
  598. // Set ID
  599. if (cable->id < 0) {
  600. // Automatically assign ID
  601. cable->id = internal->nextCableId++;
  602. }
  603. else {
  604. // Manual ID
  605. // Check that the ID is not already taken
  606. for (Cable* w : internal->cables) {
  607. assert(cable->id != w->id);
  608. }
  609. if (cable->id >= internal->nextCableId) {
  610. internal->nextCableId = cable->id + 1;
  611. }
  612. }
  613. // Add the cable
  614. internal->cables.push_back(cable);
  615. Engine_updateConnected(this);
  616. // Trigger input port event
  617. {
  618. Module::PortChangeEvent e;
  619. e.connecting = true;
  620. e.type = Port::INPUT;
  621. e.portId = cable->inputId;
  622. cable->inputModule->onPortChange(e);
  623. }
  624. // Trigger output port event if its state went from disconnected to connected.
  625. if (!outputWasConnected) {
  626. Module::PortChangeEvent e;
  627. e.connecting = true;
  628. e.type = Port::OUTPUT;
  629. e.portId = cable->outputId;
  630. cable->outputModule->onPortChange(e);
  631. }
  632. // DEBUG("Added cable %d to engine", cable->id);
  633. }
  634. void Engine::removeCable(Cable* cable) {
  635. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  636. assert(cable);
  637. // Check that the cable is already added
  638. auto it = std::find(internal->cables.begin(), internal->cables.end(), cable);
  639. assert(it != internal->cables.end());
  640. // Remove the cable
  641. internal->cables.erase(it);
  642. Engine_updateConnected(this);
  643. bool outputIsConnected = false;
  644. for (Cable* cable2 : internal->cables) {
  645. // Get connected status of output, to decide whether we need to call a PortChangeEvent.
  646. // It's best to not trust `cable->outputModule->outputs[cable->outputId]->isConnected()`
  647. if (cable2->outputModule == cable->outputModule && cable2->outputId == cable->outputId)
  648. outputIsConnected = true;
  649. }
  650. // Trigger input port event
  651. {
  652. Module::PortChangeEvent e;
  653. e.connecting = false;
  654. e.type = Port::INPUT;
  655. e.portId = cable->inputId;
  656. cable->inputModule->onPortChange(e);
  657. }
  658. // Trigger output port event if its state went from connected to disconnected.
  659. if (!outputIsConnected) {
  660. Module::PortChangeEvent e;
  661. e.connecting = false;
  662. e.type = Port::OUTPUT;
  663. e.portId = cable->outputId;
  664. cable->outputModule->onPortChange(e);
  665. }
  666. // DEBUG("Removed cable %d to engine", cable->id);
  667. }
  668. Cable* Engine::getCable(int cableId) {
  669. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  670. // Find Cable
  671. for (Cable* cable : internal->cables) {
  672. if (cable->id == cableId)
  673. return cable;
  674. }
  675. return NULL;
  676. }
  677. void Engine::setParam(Module* module, int paramId, float value) {
  678. // No lock, for performance
  679. // If param is being smoothed, cancel smoothing.
  680. if (internal->smoothModule == module && internal->smoothParamId == paramId) {
  681. internal->smoothModule = NULL;
  682. internal->smoothParamId = 0;
  683. }
  684. module->params[paramId].value = value;
  685. }
  686. float Engine::getParam(Module* module, int paramId) {
  687. // No lock, for performance
  688. return module->params[paramId].value;
  689. }
  690. void Engine::setSmoothParam(Module* module, int paramId, float value) {
  691. // No lock, for performance
  692. // If another param is being smoothed, jump value
  693. if (internal->smoothModule && !(internal->smoothModule == module && internal->smoothParamId == paramId)) {
  694. internal->smoothModule->params[internal->smoothParamId].value = internal->smoothValue;
  695. }
  696. internal->smoothParamId = paramId;
  697. internal->smoothValue = value;
  698. // Set this last so the above values are valid as soon as it is set
  699. internal->smoothModule = module;
  700. }
  701. float Engine::getSmoothParam(Module* module, int paramId) {
  702. // No lock, for performance
  703. if (internal->smoothModule == module && internal->smoothParamId == paramId)
  704. return internal->smoothValue;
  705. return getParam(module, paramId);
  706. }
  707. static void Engine_refreshParamHandleCache(Engine* that) {
  708. // Clear cache
  709. that->internal->paramHandleCache.clear();
  710. // Add active ParamHandles to cache
  711. for (ParamHandle* paramHandle : that->internal->paramHandles) {
  712. if (paramHandle->moduleId >= 0) {
  713. that->internal->paramHandleCache[std::make_tuple(paramHandle->moduleId, paramHandle->paramId)] = paramHandle;
  714. }
  715. }
  716. }
  717. void Engine::addParamHandle(ParamHandle* paramHandle) {
  718. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  719. // New ParamHandles must be blank.
  720. // This means we don't have to refresh the cache.
  721. assert(paramHandle->moduleId < 0);
  722. // Check that the ParamHandle is not already added
  723. auto it = internal->paramHandles.find(paramHandle);
  724. assert(it == internal->paramHandles.end());
  725. // Add it
  726. internal->paramHandles.insert(paramHandle);
  727. }
  728. void Engine::removeParamHandle(ParamHandle* paramHandle) {
  729. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  730. // Check that the ParamHandle is already added
  731. auto it = internal->paramHandles.find(paramHandle);
  732. assert(it != internal->paramHandles.end());
  733. // Remove it
  734. paramHandle->module = NULL;
  735. internal->paramHandles.erase(it);
  736. Engine_refreshParamHandleCache(this);
  737. }
  738. ParamHandle* Engine::getParamHandle(int moduleId, int paramId) {
  739. // No lock, for performance
  740. auto it = internal->paramHandleCache.find(std::make_tuple(moduleId, paramId));
  741. if (it == internal->paramHandleCache.end())
  742. return NULL;
  743. return it->second;
  744. }
  745. ParamHandle* Engine::getParamHandle(Module* module, int paramId) {
  746. // No lock, for performance
  747. return getParamHandle(module->id, paramId);
  748. }
  749. void Engine::updateParamHandle(ParamHandle* paramHandle, int moduleId, int paramId, bool overwrite) {
  750. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  751. // Check that it exists
  752. auto it = internal->paramHandles.find(paramHandle);
  753. assert(it != internal->paramHandles.end());
  754. // Set IDs
  755. paramHandle->moduleId = moduleId;
  756. paramHandle->paramId = paramId;
  757. paramHandle->module = NULL;
  758. // At this point, the ParamHandle cache might be invalid.
  759. if (paramHandle->moduleId >= 0) {
  760. // Replace old ParamHandle, or reset the current ParamHandle
  761. ParamHandle* oldParamHandle = getParamHandle(moduleId, paramId);
  762. if (oldParamHandle) {
  763. if (overwrite) {
  764. oldParamHandle->moduleId = -1;
  765. oldParamHandle->paramId = 0;
  766. oldParamHandle->module = NULL;
  767. }
  768. else {
  769. paramHandle->moduleId = -1;
  770. paramHandle->paramId = 0;
  771. paramHandle->module = NULL;
  772. }
  773. }
  774. }
  775. // Set module pointer if the above block didn't reset it
  776. if (paramHandle->moduleId >= 0) {
  777. paramHandle->module = getModule(paramHandle->moduleId);
  778. }
  779. Engine_refreshParamHandleCache(this);
  780. }
  781. json_t* Engine::toJson() {
  782. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  783. json_t* rootJ = json_object();
  784. // modules
  785. json_t* modulesJ = json_array();
  786. for (Module* module : internal->modules) {
  787. // module
  788. json_t* moduleJ = module->toJson();
  789. json_array_append_new(modulesJ, moduleJ);
  790. }
  791. json_object_set_new(rootJ, "modules", modulesJ);
  792. // cables
  793. json_t* cablesJ = json_array();
  794. for (Cable* cable : internal->cables) {
  795. // cable
  796. json_t* cableJ = cable->toJson();
  797. json_array_append_new(cablesJ, cableJ);
  798. }
  799. json_object_set_new(rootJ, "cables", cablesJ);
  800. return rootJ;
  801. }
  802. void Engine::fromJson(json_t* rootJ) {
  803. // Don't lock here because Module::fromJson for example might deadlock, and we actually don't really need thread safety other than the addModule() and addCable() calls, which are already behind locks.
  804. // std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  805. // modules
  806. json_t* modulesJ = json_object_get(rootJ, "modules");
  807. if (!modulesJ)
  808. return;
  809. size_t moduleIndex;
  810. json_t* moduleJ;
  811. json_array_foreach(modulesJ, moduleIndex, moduleJ) {
  812. try {
  813. Module* module = plugin::moduleFromJson(moduleJ);
  814. // Before 1.0, the module ID was the index in the "modules" array
  815. if (APP->patch->isLegacy(2)) {
  816. module->id = moduleIndex;
  817. }
  818. addModule(module);
  819. }
  820. catch (Exception& e) {
  821. APP->patch->log(e.what());
  822. }
  823. }
  824. // cables
  825. json_t* cablesJ = json_object_get(rootJ, "cables");
  826. // Before 1.0, cables were called wires
  827. if (!cablesJ)
  828. cablesJ = json_object_get(rootJ, "wires");
  829. if (!cablesJ)
  830. return;
  831. size_t cableIndex;
  832. json_t* cableJ;
  833. json_array_foreach(cablesJ, cableIndex, cableJ) {
  834. // cable
  835. Cable* cable = new Cable;
  836. try {
  837. cable->fromJson(cableJ);
  838. addCable(cable);
  839. }
  840. catch (Exception& e) {
  841. delete cable;
  842. // Don't log exceptions because missing modules create unnecessary complaining when cables try to connect to them.
  843. }
  844. }
  845. }
  846. void EngineWorker::run() {
  847. // Configure thread
  848. system::setThreadName(string::f("Worker %d", id));
  849. initMXCSR();
  850. random::init();
  851. while (true) {
  852. engine->internal->engineBarrier.wait();
  853. if (!running)
  854. return;
  855. Engine_stepModulesWorker(engine, id);
  856. engine->internal->workerBarrier.wait();
  857. }
  858. }
  859. } // namespace engine
  860. } // namespace rack