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.

1256 lines
30KB

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