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.

1032 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. // Don't delete paramHandle because they're owned by other things (e.g. Modules)
  342. }
  343. std::vector<Cable*> cables = internal->cables;
  344. for (Cable* cable : cables) {
  345. removeCable(cable);
  346. delete cable;
  347. }
  348. std::vector<Module*> modules = internal->modules;
  349. for (Module* module : modules) {
  350. removeModule(module);
  351. delete module;
  352. }
  353. // Reset engine state
  354. internal->nextModuleId = 0;
  355. internal->nextCableId = 0;
  356. }
  357. void Engine::step(int frames) {
  358. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  359. // Configure thread
  360. initMXCSR();
  361. random::init();
  362. // Set sample rate
  363. if (internal->sampleRate != settings::sampleRate) {
  364. internal->sampleRate = settings::sampleRate;
  365. internal->sampleTime = 1 / internal->sampleRate;
  366. Module::SampleRateChangeEvent e;
  367. e.sampleRate = internal->sampleRate;
  368. e.sampleTime = internal->sampleTime;
  369. for (Module* module : internal->modules) {
  370. module->onSampleRateChange(e);
  371. }
  372. }
  373. if (!internal->paused) {
  374. // Launch workers
  375. if (internal->threadCount != settings::threadCount) {
  376. Engine_relaunchWorkers(this, settings::threadCount);
  377. }
  378. // Update expander pointers
  379. for (Module* module : internal->modules) {
  380. Engine_updateExpander(this, &module->leftExpander);
  381. Engine_updateExpander(this, &module->rightExpander);
  382. }
  383. // Step modules
  384. for (int i = 0; i < frames; i++) {
  385. Engine_stepModules(this);
  386. }
  387. }
  388. else {
  389. // Stop workers while paused
  390. if (internal->threadCount != 1) {
  391. Engine_relaunchWorkers(this, 1);
  392. }
  393. }
  394. yieldWorkers();
  395. }
  396. void Engine::setPrimaryModule(Module* module) {
  397. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  398. internal->primaryModule = module;
  399. }
  400. Module* Engine::getPrimaryModule() {
  401. // No lock, for performance
  402. return internal->primaryModule;
  403. }
  404. void Engine::setPaused(bool paused) {
  405. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  406. internal->paused = paused;
  407. }
  408. bool Engine::isPaused() {
  409. // No lock, for performance
  410. return internal->paused;
  411. }
  412. float Engine::getSampleRate() {
  413. // No lock, for performance
  414. return internal->sampleRate;
  415. }
  416. float Engine::getSampleTime() {
  417. // No lock, for performance
  418. return internal->sampleTime;
  419. }
  420. void Engine::yieldWorkers() {
  421. internal->workerBarrier.yield = true;
  422. }
  423. uint64_t Engine::getFrame() {
  424. // No lock, for performance
  425. return internal->frame;
  426. }
  427. void Engine::addModule(Module* module) {
  428. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  429. assert(module);
  430. // Check that the module is not already added
  431. auto it = std::find(internal->modules.begin(), internal->modules.end(), module);
  432. assert(it == internal->modules.end());
  433. // Set ID
  434. if (module->id < 0) {
  435. // Automatically assign ID
  436. module->id = internal->nextModuleId++;
  437. }
  438. else {
  439. // Manual ID
  440. // Check that the ID is not already taken
  441. for (Module* m : internal->modules) {
  442. assert(module->id != m->id);
  443. }
  444. if (module->id >= internal->nextModuleId) {
  445. internal->nextModuleId = module->id + 1;
  446. }
  447. }
  448. // Add module
  449. internal->modules.push_back(module);
  450. // Trigger Add event
  451. Module::AddEvent eAdd;
  452. module->onAdd(eAdd);
  453. // Update ParamHandles' module pointers
  454. for (ParamHandle* paramHandle : internal->paramHandles) {
  455. if (paramHandle->moduleId == module->id)
  456. paramHandle->module = module;
  457. }
  458. // DEBUG("Added module %d to engine", module->id);
  459. }
  460. void Engine::removeModule(Module* module) {
  461. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  462. assert(module);
  463. // Check that the module actually exists
  464. auto it = std::find(internal->modules.begin(), internal->modules.end(), module);
  465. assert(it != internal->modules.end());
  466. // If a param is being smoothed on this module, stop smoothing it immediately
  467. if (module == internal->smoothModule) {
  468. internal->smoothModule = NULL;
  469. }
  470. // Check that all cables are disconnected
  471. for (Cable* cable : internal->cables) {
  472. assert(cable->inputModule != module);
  473. assert(cable->outputModule != module);
  474. }
  475. // Update ParamHandles' module pointers
  476. for (ParamHandle* paramHandle : internal->paramHandles) {
  477. if (paramHandle->moduleId == module->id)
  478. paramHandle->module = NULL;
  479. }
  480. // Update expander pointers
  481. for (Module* m : internal->modules) {
  482. if (m->leftExpander.module == module) {
  483. m->leftExpander.moduleId = -1;
  484. m->leftExpander.module = NULL;
  485. }
  486. if (m->rightExpander.module == module) {
  487. m->rightExpander.moduleId = -1;
  488. m->rightExpander.module = NULL;
  489. }
  490. }
  491. // Trigger Remove event
  492. Module::RemoveEvent eRemove;
  493. module->onRemove(eRemove);
  494. // Unset primary module
  495. if (internal->primaryModule == module)
  496. internal->primaryModule = NULL;
  497. // Remove module
  498. internal->modules.erase(it);
  499. // DEBUG("Removed module %d to engine", module->id);
  500. }
  501. Module* Engine::getModule(int moduleId) {
  502. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  503. // Find module
  504. for (Module* module : internal->modules) {
  505. if (module->id == moduleId)
  506. return module;
  507. }
  508. return NULL;
  509. }
  510. void Engine::resetModule(Module* module) {
  511. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  512. assert(module);
  513. Module::ResetEvent eReset;
  514. module->onReset(eReset);
  515. }
  516. void Engine::randomizeModule(Module* module) {
  517. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  518. assert(module);
  519. Module::RandomizeEvent eRandomize;
  520. module->onRandomize(eRandomize);
  521. }
  522. void Engine::bypassModule(Module* module, bool bypassed) {
  523. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  524. assert(module);
  525. if (module->bypassed() == bypassed)
  526. return;
  527. // Clear outputs and set to 1 channel
  528. for (Output& output : module->outputs) {
  529. // This zeros all voltages, but the channel is set to 1 if connected
  530. output.setChannels(0);
  531. }
  532. module->bypassed() = bypassed;
  533. // Trigger event
  534. if (bypassed) {
  535. Module::BypassEvent eBypass;
  536. module->onBypass(eBypass);
  537. }
  538. else {
  539. Module::UnBypassEvent eUnBypass;
  540. module->onUnBypass(eUnBypass);
  541. }
  542. }
  543. static void Port_setDisconnected(Port* that) {
  544. that->channels = 0;
  545. for (int c = 0; c < PORT_MAX_CHANNELS; c++) {
  546. that->voltages[c] = 0.f;
  547. }
  548. }
  549. static void Port_setConnected(Port* that) {
  550. if (that->channels > 0)
  551. return;
  552. that->channels = 1;
  553. }
  554. static void Engine_updateConnected(Engine* that) {
  555. // Find disconnected ports
  556. std::set<Port*> disconnectedPorts;
  557. for (Module* module : that->internal->modules) {
  558. for (Input& input : module->inputs) {
  559. disconnectedPorts.insert(&input);
  560. }
  561. for (Output& output : module->outputs) {
  562. disconnectedPorts.insert(&output);
  563. }
  564. }
  565. for (Cable* cable : that->internal->cables) {
  566. // Connect input
  567. Input& input = cable->inputModule->inputs[cable->inputId];
  568. auto inputIt = disconnectedPorts.find(&input);
  569. if (inputIt != disconnectedPorts.end())
  570. disconnectedPorts.erase(inputIt);
  571. Port_setConnected(&input);
  572. // Connect output
  573. Output& output = cable->outputModule->outputs[cable->outputId];
  574. auto outputIt = disconnectedPorts.find(&output);
  575. if (outputIt != disconnectedPorts.end())
  576. disconnectedPorts.erase(outputIt);
  577. Port_setConnected(&output);
  578. }
  579. // Disconnect ports that have no cable
  580. for (Port* port : disconnectedPorts) {
  581. Port_setDisconnected(port);
  582. }
  583. }
  584. void Engine::addCable(Cable* cable) {
  585. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  586. assert(cable);
  587. // Check cable properties
  588. assert(cable->inputModule);
  589. assert(cable->outputModule);
  590. bool outputWasConnected = false;
  591. for (Cable* cable2 : internal->cables) {
  592. // Check that the cable is not already added
  593. assert(cable2 != cable);
  594. // Check that the input is not already used by another cable
  595. assert(!(cable2->inputModule == cable->inputModule && cable2->inputId == cable->inputId));
  596. // Get connected status of output, to decide whether we need to call a PortChangeEvent.
  597. // It's best to not trust `cable->outputModule->outputs[cable->outputId]->isConnected()`
  598. if (cable2->outputModule == cable->outputModule && cable2->outputId == cable->outputId)
  599. outputWasConnected = true;
  600. }
  601. // Set ID
  602. if (cable->id < 0) {
  603. // Automatically assign ID
  604. cable->id = internal->nextCableId++;
  605. }
  606. else {
  607. // Manual ID
  608. // Check that the ID is not already taken
  609. for (Cable* w : internal->cables) {
  610. assert(cable->id != w->id);
  611. }
  612. if (cable->id >= internal->nextCableId) {
  613. internal->nextCableId = cable->id + 1;
  614. }
  615. }
  616. // Add the cable
  617. internal->cables.push_back(cable);
  618. Engine_updateConnected(this);
  619. // Trigger 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. // Trigger 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. // DEBUG("Added cable %d to engine", cable->id);
  636. }
  637. void Engine::removeCable(Cable* cable) {
  638. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  639. assert(cable);
  640. // Check that the cable is already added
  641. auto it = std::find(internal->cables.begin(), internal->cables.end(), cable);
  642. assert(it != internal->cables.end());
  643. // Remove the cable
  644. internal->cables.erase(it);
  645. Engine_updateConnected(this);
  646. bool outputIsConnected = false;
  647. for (Cable* cable2 : internal->cables) {
  648. // Get connected status of output, to decide whether we need to call a PortChangeEvent.
  649. // It's best to not trust `cable->outputModule->outputs[cable->outputId]->isConnected()`
  650. if (cable2->outputModule == cable->outputModule && cable2->outputId == cable->outputId)
  651. outputIsConnected = true;
  652. }
  653. // Trigger input port event
  654. {
  655. Module::PortChangeEvent e;
  656. e.connecting = false;
  657. e.type = Port::INPUT;
  658. e.portId = cable->inputId;
  659. cable->inputModule->onPortChange(e);
  660. }
  661. // Trigger output port event if its state went from connected to disconnected.
  662. if (!outputIsConnected) {
  663. Module::PortChangeEvent e;
  664. e.connecting = false;
  665. e.type = Port::OUTPUT;
  666. e.portId = cable->outputId;
  667. cable->outputModule->onPortChange(e);
  668. }
  669. // DEBUG("Removed cable %d to engine", cable->id);
  670. }
  671. Cable* Engine::getCable(int cableId) {
  672. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  673. // Find Cable
  674. for (Cable* cable : internal->cables) {
  675. if (cable->id == cableId)
  676. return cable;
  677. }
  678. return NULL;
  679. }
  680. void Engine::setParam(Module* module, int paramId, float value) {
  681. // No lock, for performance
  682. // If param is being smoothed, cancel smoothing.
  683. if (internal->smoothModule == module && internal->smoothParamId == paramId) {
  684. internal->smoothModule = NULL;
  685. internal->smoothParamId = 0;
  686. }
  687. module->params[paramId].value = value;
  688. }
  689. float Engine::getParam(Module* module, int paramId) {
  690. // No lock, for performance
  691. return module->params[paramId].value;
  692. }
  693. void Engine::setSmoothParam(Module* module, int paramId, float value) {
  694. // No lock, for performance
  695. // If another param is being smoothed, jump value
  696. if (internal->smoothModule && !(internal->smoothModule == module && internal->smoothParamId == paramId)) {
  697. internal->smoothModule->params[internal->smoothParamId].value = internal->smoothValue;
  698. }
  699. internal->smoothParamId = paramId;
  700. internal->smoothValue = value;
  701. // Set this last so the above values are valid as soon as it is set
  702. internal->smoothModule = module;
  703. }
  704. float Engine::getSmoothParam(Module* module, int paramId) {
  705. // No lock, for performance
  706. if (internal->smoothModule == module && internal->smoothParamId == paramId)
  707. return internal->smoothValue;
  708. return getParam(module, paramId);
  709. }
  710. static void Engine_refreshParamHandleCache(Engine* that) {
  711. // Clear cache
  712. that->internal->paramHandleCache.clear();
  713. // Add active ParamHandles to cache
  714. for (ParamHandle* paramHandle : that->internal->paramHandles) {
  715. if (paramHandle->moduleId >= 0) {
  716. that->internal->paramHandleCache[std::make_tuple(paramHandle->moduleId, paramHandle->paramId)] = paramHandle;
  717. }
  718. }
  719. }
  720. void Engine::addParamHandle(ParamHandle* paramHandle) {
  721. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  722. // New ParamHandles must be blank.
  723. // This means we don't have to refresh the cache.
  724. assert(paramHandle->moduleId < 0);
  725. // Check that the ParamHandle is not already added
  726. auto it = internal->paramHandles.find(paramHandle);
  727. assert(it == internal->paramHandles.end());
  728. // Add it
  729. internal->paramHandles.insert(paramHandle);
  730. }
  731. void Engine::removeParamHandle(ParamHandle* paramHandle) {
  732. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  733. // Check that the ParamHandle is already added
  734. auto it = internal->paramHandles.find(paramHandle);
  735. assert(it != internal->paramHandles.end());
  736. // Remove it
  737. paramHandle->module = NULL;
  738. internal->paramHandles.erase(it);
  739. Engine_refreshParamHandleCache(this);
  740. }
  741. ParamHandle* Engine::getParamHandle(int moduleId, int paramId) {
  742. // No lock, for performance
  743. auto it = internal->paramHandleCache.find(std::make_tuple(moduleId, paramId));
  744. if (it == internal->paramHandleCache.end())
  745. return NULL;
  746. return it->second;
  747. }
  748. ParamHandle* Engine::getParamHandle(Module* module, int paramId) {
  749. // No lock, for performance
  750. return getParamHandle(module->id, paramId);
  751. }
  752. void Engine::updateParamHandle(ParamHandle* paramHandle, int moduleId, int paramId, bool overwrite) {
  753. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  754. // Check that it exists
  755. auto it = internal->paramHandles.find(paramHandle);
  756. assert(it != internal->paramHandles.end());
  757. // Set IDs
  758. paramHandle->moduleId = moduleId;
  759. paramHandle->paramId = paramId;
  760. paramHandle->module = NULL;
  761. // At this point, the ParamHandle cache might be invalid.
  762. if (paramHandle->moduleId >= 0) {
  763. // Replace old ParamHandle, or reset the current ParamHandle
  764. ParamHandle* oldParamHandle = getParamHandle(moduleId, paramId);
  765. if (oldParamHandle) {
  766. if (overwrite) {
  767. oldParamHandle->moduleId = -1;
  768. oldParamHandle->paramId = 0;
  769. oldParamHandle->module = NULL;
  770. }
  771. else {
  772. paramHandle->moduleId = -1;
  773. paramHandle->paramId = 0;
  774. paramHandle->module = NULL;
  775. }
  776. }
  777. }
  778. // Set module pointer if the above block didn't reset it
  779. if (paramHandle->moduleId >= 0) {
  780. paramHandle->module = getModule(paramHandle->moduleId);
  781. }
  782. Engine_refreshParamHandleCache(this);
  783. }
  784. json_t* Engine::toJson() {
  785. std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  786. json_t* rootJ = json_object();
  787. // modules
  788. json_t* modulesJ = json_array();
  789. for (Module* module : internal->modules) {
  790. // module
  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. // cable
  799. json_t* cableJ = cable->toJson();
  800. json_array_append_new(cablesJ, cableJ);
  801. }
  802. json_object_set_new(rootJ, "cables", cablesJ);
  803. return rootJ;
  804. }
  805. void Engine::fromJson(json_t* rootJ) {
  806. // 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.
  807. // std::lock_guard<std::recursive_mutex> lock(internal->mutex);
  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. try {
  816. Module* module = plugin::moduleFromJson(moduleJ);
  817. // Before 1.0, the module ID was the index in the "modules" array
  818. if (APP->patch->isLegacy(2)) {
  819. module->id = moduleIndex;
  820. }
  821. addModule(module);
  822. }
  823. catch (Exception& e) {
  824. APP->patch->log(e.what());
  825. }
  826. }
  827. // cables
  828. json_t* cablesJ = json_object_get(rootJ, "cables");
  829. // Before 1.0, cables were called wires
  830. if (!cablesJ)
  831. cablesJ = json_object_get(rootJ, "wires");
  832. if (!cablesJ)
  833. return;
  834. size_t cableIndex;
  835. json_t* cableJ;
  836. json_array_foreach(cablesJ, cableIndex, cableJ) {
  837. // cable
  838. Cable* cable = new Cable;
  839. try {
  840. cable->fromJson(cableJ);
  841. addCable(cable);
  842. }
  843. catch (Exception& e) {
  844. delete cable;
  845. // Don't log exceptions because missing modules create unnecessary complaining when cables try to connect to them.
  846. }
  847. }
  848. }
  849. void EngineWorker::run() {
  850. // Configure thread
  851. system::setThreadName(string::f("Worker %d", id));
  852. initMXCSR();
  853. random::init();
  854. while (true) {
  855. engine->internal->engineBarrier.wait();
  856. if (!running)
  857. return;
  858. Engine_stepModulesWorker(engine, id);
  859. engine->internal->workerBarrier.wait();
  860. }
  861. }
  862. } // namespace engine
  863. } // namespace rack