Audio plugin host https://kx.studio/carla
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.

876 lines
21KB

  1. /*
  2. * Carla Plugin
  3. * Copyright (C) 2011-2019 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #include "CarlaPluginInternal.hpp"
  18. #include "CarlaEngine.hpp"
  19. #include "CarlaLibCounter.hpp"
  20. #include "CarlaMathUtils.hpp"
  21. CARLA_BACKEND_START_NAMESPACE
  22. // -------------------------------------------------------------------
  23. // Fallback data
  24. static const MidiProgramData kMidiProgramDataNull = { 0, 0, nullptr };
  25. static /* */ CustomData kCustomDataFallbackNC = { nullptr, nullptr, nullptr };
  26. // -----------------------------------------------------------------------
  27. // PluginAudioData
  28. PluginAudioData::PluginAudioData() noexcept
  29. : count(0),
  30. ports(nullptr) {}
  31. PluginAudioData::~PluginAudioData() noexcept
  32. {
  33. CARLA_SAFE_ASSERT_INT(count == 0, count);
  34. CARLA_SAFE_ASSERT(ports == nullptr);
  35. }
  36. void PluginAudioData::createNew(const uint32_t newCount)
  37. {
  38. CARLA_SAFE_ASSERT_INT(count == 0, count);
  39. CARLA_SAFE_ASSERT_RETURN(ports == nullptr,);
  40. CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
  41. ports = new PluginAudioPort[newCount];
  42. carla_zeroStructs(ports, newCount);
  43. count = newCount;
  44. }
  45. void PluginAudioData::clear() noexcept
  46. {
  47. if (ports != nullptr)
  48. {
  49. for (uint32_t i=0; i < count; ++i)
  50. {
  51. if (ports[i].port != nullptr)
  52. {
  53. delete ports[i].port;
  54. ports[i].port = nullptr;
  55. }
  56. }
  57. delete[] ports;
  58. ports = nullptr;
  59. }
  60. count = 0;
  61. }
  62. void PluginAudioData::initBuffers() const noexcept
  63. {
  64. for (uint32_t i=0; i < count; ++i)
  65. {
  66. if (ports[i].port != nullptr)
  67. ports[i].port->initBuffer();
  68. }
  69. }
  70. // -----------------------------------------------------------------------
  71. // PluginCVData
  72. PluginCVData::PluginCVData() noexcept
  73. : count(0),
  74. ports(nullptr) {}
  75. PluginCVData::~PluginCVData() noexcept
  76. {
  77. CARLA_SAFE_ASSERT_INT(count == 0, count);
  78. CARLA_SAFE_ASSERT(ports == nullptr);
  79. }
  80. void PluginCVData::createNew(const uint32_t newCount)
  81. {
  82. CARLA_SAFE_ASSERT_INT(count == 0, count);
  83. CARLA_SAFE_ASSERT_RETURN(ports == nullptr,);
  84. CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
  85. ports = new PluginCVPort[newCount];
  86. carla_zeroStructs(ports, newCount);
  87. count = newCount;
  88. }
  89. void PluginCVData::clear() noexcept
  90. {
  91. if (ports != nullptr)
  92. {
  93. for (uint32_t i=0; i < count; ++i)
  94. {
  95. if (ports[i].port != nullptr)
  96. {
  97. delete ports[i].port;
  98. ports[i].port = nullptr;
  99. }
  100. }
  101. delete[] ports;
  102. ports = nullptr;
  103. }
  104. count = 0;
  105. }
  106. void PluginCVData::initBuffers() const noexcept
  107. {
  108. for (uint32_t i=0; i < count; ++i)
  109. {
  110. if (ports[i].port != nullptr)
  111. ports[i].port->initBuffer();
  112. }
  113. }
  114. // -----------------------------------------------------------------------
  115. // PluginEventData
  116. PluginEventData::PluginEventData() noexcept
  117. : portIn(nullptr),
  118. portOut(nullptr)
  119. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  120. , cvSourcePorts(nullptr)
  121. #endif
  122. {
  123. }
  124. PluginEventData::~PluginEventData() noexcept
  125. {
  126. CARLA_SAFE_ASSERT(portIn == nullptr);
  127. CARLA_SAFE_ASSERT(portOut == nullptr);
  128. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  129. CARLA_SAFE_ASSERT(cvSourcePorts == nullptr);
  130. #endif
  131. }
  132. void PluginEventData::clear() noexcept
  133. {
  134. if (portIn != nullptr)
  135. {
  136. delete portIn;
  137. portIn = nullptr;
  138. }
  139. if (portOut != nullptr)
  140. {
  141. delete portOut;
  142. portOut = nullptr;
  143. }
  144. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  145. if (cvSourcePorts != nullptr)
  146. {
  147. delete cvSourcePorts;
  148. cvSourcePorts = nullptr;
  149. }
  150. #endif
  151. }
  152. void PluginEventData::initBuffers() const noexcept
  153. {
  154. if (portIn != nullptr)
  155. portIn->initBuffer();
  156. if (portOut != nullptr)
  157. portOut->initBuffer();
  158. }
  159. // -----------------------------------------------------------------------
  160. // PluginParameterData
  161. PluginParameterData::PluginParameterData() noexcept
  162. : count(0),
  163. data(nullptr),
  164. ranges(nullptr),
  165. special(nullptr) {}
  166. PluginParameterData::~PluginParameterData() noexcept
  167. {
  168. CARLA_SAFE_ASSERT_INT(count == 0, count);
  169. CARLA_SAFE_ASSERT(data == nullptr);
  170. CARLA_SAFE_ASSERT(ranges == nullptr);
  171. CARLA_SAFE_ASSERT(special == nullptr);
  172. }
  173. void PluginParameterData::createNew(const uint32_t newCount, const bool withSpecial)
  174. {
  175. CARLA_SAFE_ASSERT_INT(count == 0, count);
  176. CARLA_SAFE_ASSERT_RETURN(data == nullptr,);
  177. CARLA_SAFE_ASSERT_RETURN(ranges == nullptr,);
  178. CARLA_SAFE_ASSERT_RETURN(special == nullptr,);
  179. CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
  180. data = new ParameterData[newCount];
  181. carla_zeroStructs(data, newCount);
  182. for (uint32_t i=0; i < newCount; ++i)
  183. {
  184. data[i].index = PARAMETER_NULL;
  185. data[i].rindex = PARAMETER_NULL;
  186. data[i].mappedControlIndex = CONTROL_INDEX_NONE;
  187. }
  188. ranges = new ParameterRanges[newCount];
  189. carla_zeroStructs(ranges, newCount);
  190. if (withSpecial)
  191. {
  192. special = new SpecialParameterType[newCount];
  193. carla_zeroStructs(special, newCount);
  194. }
  195. count = newCount;
  196. }
  197. void PluginParameterData::clear() noexcept
  198. {
  199. if (data != nullptr)
  200. {
  201. delete[] data;
  202. data = nullptr;
  203. }
  204. if (ranges != nullptr)
  205. {
  206. delete[] ranges;
  207. ranges = nullptr;
  208. }
  209. if (special != nullptr)
  210. {
  211. delete[] special;
  212. special = nullptr;
  213. }
  214. count = 0;
  215. }
  216. float PluginParameterData::getFixedValue(const uint32_t parameterId, float value) const noexcept
  217. {
  218. CARLA_SAFE_ASSERT_RETURN(parameterId < count, 0.0f);
  219. const uint paramHints (data[parameterId].hints);
  220. const ParameterRanges& paramRanges(ranges[parameterId]);
  221. // if boolean, return either min or max
  222. if (paramHints & PARAMETER_IS_BOOLEAN)
  223. {
  224. const float middlePoint = paramRanges.min + (paramRanges.max-paramRanges.min)/2.0f;
  225. return value >= middlePoint ? paramRanges.max : paramRanges.min;
  226. }
  227. // if integer, round first
  228. if (paramHints & PARAMETER_IS_INTEGER)
  229. return paramRanges.getFixedValue(std::round(value));
  230. // normal mode
  231. return paramRanges.getFixedValue(value);
  232. }
  233. // -----------------------------------------------------------------------
  234. // PluginProgramData
  235. PluginProgramData::PluginProgramData() noexcept
  236. : count(0),
  237. current(-1),
  238. names(nullptr) {}
  239. PluginProgramData::~PluginProgramData() noexcept
  240. {
  241. CARLA_SAFE_ASSERT_INT(count == 0, count);
  242. CARLA_SAFE_ASSERT_INT(current == -1, current);
  243. CARLA_SAFE_ASSERT(names == nullptr);
  244. }
  245. void PluginProgramData::createNew(const uint32_t newCount)
  246. {
  247. CARLA_SAFE_ASSERT_INT(count == 0, count);
  248. CARLA_SAFE_ASSERT_INT(current == -1, current);
  249. CARLA_SAFE_ASSERT_RETURN(names == nullptr,);
  250. CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
  251. names = new ProgramName[newCount];
  252. carla_zeroStructs(names, newCount);
  253. count = newCount;
  254. current = -1;
  255. }
  256. void PluginProgramData::clear() noexcept
  257. {
  258. if (names != nullptr)
  259. {
  260. for (uint32_t i=0; i < count; ++i)
  261. {
  262. if (names[i] != nullptr)
  263. {
  264. delete[] names[i];
  265. names[i] = nullptr;
  266. }
  267. }
  268. delete[] names;
  269. names = nullptr;
  270. }
  271. count = 0;
  272. current = -1;
  273. }
  274. // -----------------------------------------------------------------------
  275. // PluginMidiProgramData
  276. PluginMidiProgramData::PluginMidiProgramData() noexcept
  277. : count(0),
  278. current(-1),
  279. data(nullptr) {}
  280. PluginMidiProgramData::~PluginMidiProgramData() noexcept
  281. {
  282. CARLA_SAFE_ASSERT_INT(count == 0, count);
  283. CARLA_SAFE_ASSERT_INT(current == -1, current);
  284. CARLA_SAFE_ASSERT(data == nullptr);
  285. }
  286. void PluginMidiProgramData::createNew(const uint32_t newCount)
  287. {
  288. CARLA_SAFE_ASSERT_INT(count == 0, count);
  289. CARLA_SAFE_ASSERT_INT(current == -1, current);
  290. CARLA_SAFE_ASSERT_RETURN(data == nullptr,);
  291. CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
  292. data = new MidiProgramData[newCount];
  293. carla_zeroStructs(data, newCount);
  294. count = newCount;
  295. current = -1;
  296. }
  297. void PluginMidiProgramData::clear() noexcept
  298. {
  299. if (data != nullptr)
  300. {
  301. for (uint32_t i=0; i < count; ++i)
  302. {
  303. if (data[i].name != nullptr)
  304. {
  305. delete[] data[i].name;
  306. data[i].name = nullptr;
  307. }
  308. }
  309. delete[] data;
  310. data = nullptr;
  311. }
  312. count = 0;
  313. current = -1;
  314. }
  315. const MidiProgramData& PluginMidiProgramData::getCurrent() const noexcept
  316. {
  317. CARLA_SAFE_ASSERT_RETURN(current >= 0 && current < static_cast<int32_t>(count), kMidiProgramDataNull);
  318. return data[current];
  319. }
  320. // -----------------------------------------------------------------------
  321. // ProtectedData::ExternalNotes
  322. CarlaPlugin::ProtectedData::ExternalNotes::ExternalNotes() noexcept
  323. : mutex(),
  324. dataPool(32, 152),
  325. data(dataPool) {}
  326. CarlaPlugin::ProtectedData::ExternalNotes::~ExternalNotes() noexcept
  327. {
  328. clear();
  329. }
  330. void CarlaPlugin::ProtectedData::ExternalNotes::appendNonRT(const ExternalMidiNote& note) noexcept
  331. {
  332. mutex.lock();
  333. data.append_sleepy(note);
  334. mutex.unlock();
  335. }
  336. void CarlaPlugin::ProtectedData::ExternalNotes::clear() noexcept
  337. {
  338. mutex.lock();
  339. data.clear();
  340. mutex.unlock();
  341. }
  342. // -----------------------------------------------------------------------
  343. // ProtectedData::Latency
  344. CarlaPlugin::ProtectedData::Latency::Latency() noexcept
  345. #ifdef BUILD_BRIDGE
  346. : frames(0) {}
  347. #else
  348. : frames(0),
  349. channels(0),
  350. buffers(nullptr) {}
  351. #endif
  352. #ifndef BUILD_BRIDGE
  353. CarlaPlugin::ProtectedData::Latency::~Latency() noexcept
  354. {
  355. clearBuffers();
  356. }
  357. void CarlaPlugin::ProtectedData::Latency::clearBuffers() noexcept
  358. {
  359. if (buffers != nullptr)
  360. {
  361. for (uint32_t i=0; i < channels; ++i)
  362. {
  363. CARLA_SAFE_ASSERT_CONTINUE(buffers[i] != nullptr);
  364. delete[] buffers[i];
  365. buffers[i] = nullptr;
  366. }
  367. delete[] buffers;
  368. buffers = nullptr;
  369. }
  370. channels = 0;
  371. frames = 0;
  372. }
  373. void CarlaPlugin::ProtectedData::Latency::recreateBuffers(const uint32_t newChannels, const uint32_t newFrames)
  374. {
  375. CARLA_SAFE_ASSERT_RETURN(channels != newChannels || frames != newFrames,);
  376. const bool retrieveOldBuffer = (channels == newChannels && channels > 0 && frames > 0 && newFrames > 0);
  377. float** const oldBuffers = buffers;
  378. const uint32_t oldFrames = frames;
  379. channels = newChannels;
  380. frames = newFrames;
  381. if (channels > 0 && frames > 0)
  382. {
  383. buffers = new float*[channels];
  384. for (uint32_t i=0; i < channels; ++i)
  385. {
  386. buffers[i] = new float[frames];
  387. if (retrieveOldBuffer)
  388. {
  389. if (oldFrames > frames)
  390. {
  391. const uint32_t diff = oldFrames - frames;
  392. carla_copyFloats(buffers[i], oldBuffers[i] + diff, frames);
  393. }
  394. else
  395. {
  396. const uint32_t diff = frames - oldFrames;
  397. carla_zeroFloats(buffers[i], diff);
  398. carla_copyFloats(buffers[i] + diff, oldBuffers[i], oldFrames);
  399. }
  400. }
  401. else
  402. {
  403. carla_zeroFloats(buffers[i], frames);
  404. }
  405. }
  406. }
  407. else
  408. {
  409. buffers = nullptr;
  410. }
  411. // delete old buffer
  412. if (oldBuffers != nullptr)
  413. {
  414. for (uint32_t i=0; i < channels; ++i)
  415. {
  416. CARLA_SAFE_ASSERT_CONTINUE(oldBuffers[i] != nullptr);
  417. delete[] oldBuffers[i];
  418. oldBuffers[i] = nullptr;
  419. }
  420. delete[] oldBuffers;
  421. }
  422. }
  423. #endif
  424. // -----------------------------------------------------------------------
  425. // ProtectedData::PostRtEvents
  426. CarlaPlugin::ProtectedData::PostRtEvents::PostRtEvents() noexcept
  427. : dataPool(128, 128),
  428. dataPendingRT(dataPool),
  429. data(dataPool),
  430. dataMutex(),
  431. dataPendingMutex() {}
  432. CarlaPlugin::ProtectedData::PostRtEvents::~PostRtEvents() noexcept
  433. {
  434. dataMutex.lock();
  435. data.clear();
  436. dataMutex.unlock();
  437. dataPendingMutex.lock();
  438. dataPendingRT.clear();
  439. dataPendingMutex.unlock();
  440. }
  441. void CarlaPlugin::ProtectedData::PostRtEvents::appendRT(const PluginPostRtEvent& e) noexcept
  442. {
  443. CARLA_SAFE_ASSERT_INT2_RETURN(dataPendingMutex.tryLock(), e.type, e.value1,);
  444. dataPendingRT.append(e);
  445. dataPendingMutex.unlock();
  446. }
  447. void CarlaPlugin::ProtectedData::PostRtEvents::trySplice() noexcept
  448. {
  449. const CarlaMutexTryLocker cmtl(dataPendingMutex);
  450. if (cmtl.wasLocked() && dataPendingRT.count() > 0 && dataMutex.tryLock())
  451. {
  452. dataPendingRT.moveTo(data, true);
  453. dataMutex.unlock();
  454. }
  455. }
  456. void CarlaPlugin::ProtectedData::PostRtEvents::clearData() noexcept
  457. {
  458. const bool tryLockOk(dataMutex.tryLock());
  459. CARLA_SAFE_ASSERT(! tryLockOk);
  460. data.clear();
  461. if (tryLockOk)
  462. dataMutex.unlock();
  463. }
  464. // -----------------------------------------------------------------------
  465. // ProtectedData::PostUiEvents
  466. CarlaPlugin::ProtectedData::PostUiEvents::PostUiEvents() noexcept
  467. : mutex(),
  468. data() {}
  469. CarlaPlugin::ProtectedData::PostUiEvents::~PostUiEvents() noexcept
  470. {
  471. clear();
  472. }
  473. void CarlaPlugin::ProtectedData::PostUiEvents::append(const PluginPostRtEvent& e) noexcept
  474. {
  475. mutex.lock();
  476. data.append(e);
  477. mutex.unlock();
  478. }
  479. void CarlaPlugin::ProtectedData::PostUiEvents::clear() noexcept
  480. {
  481. mutex.lock();
  482. data.clear();
  483. mutex.unlock();
  484. }
  485. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  486. // -----------------------------------------------------------------------
  487. // ProtectedData::PostProc
  488. CarlaPlugin::ProtectedData::PostProc::PostProc() noexcept
  489. : dryWet(1.0f),
  490. volume(1.0f),
  491. balanceLeft(-1.0f),
  492. balanceRight(1.0f),
  493. panning(0.0f) {}
  494. #endif
  495. // -----------------------------------------------------------------------
  496. CarlaPlugin::ProtectedData::ProtectedData(CarlaEngine* const eng, const uint idx) noexcept
  497. : engine(eng),
  498. client(nullptr),
  499. id(idx),
  500. hints(0x0),
  501. options(0x0),
  502. nodeId(0),
  503. active(false),
  504. enabled(false),
  505. needsReset(false),
  506. engineBridged(eng->getType() == kEngineTypeBridge),
  507. enginePlugin(eng->getType() == kEngineTypePlugin),
  508. lib(nullptr),
  509. uiLib(nullptr),
  510. ctrlChannel(0),
  511. extraHints(0x0),
  512. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  513. transientTryCounter(0),
  514. transientFirstTry(true),
  515. #endif
  516. name(nullptr),
  517. filename(nullptr),
  518. iconName(nullptr),
  519. audioIn(),
  520. audioOut(),
  521. cvIn(),
  522. cvOut(),
  523. event(),
  524. param(),
  525. prog(),
  526. midiprog(),
  527. custom(),
  528. masterMutex(),
  529. singleMutex(),
  530. stateSave(),
  531. extNotes(),
  532. latency(),
  533. postRtEvents(),
  534. postUiEvents()
  535. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  536. , postProc()
  537. #endif
  538. {}
  539. CarlaPlugin::ProtectedData::~ProtectedData() noexcept
  540. {
  541. CARLA_SAFE_ASSERT(! (active && needsReset));
  542. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  543. CARLA_SAFE_ASSERT(transientTryCounter == 0);
  544. #endif
  545. {
  546. // mutex MUST have been locked before
  547. const bool lockMaster(masterMutex.tryLock());
  548. const bool lockSingle(singleMutex.tryLock());
  549. CARLA_SAFE_ASSERT(! lockMaster);
  550. CARLA_SAFE_ASSERT(! lockSingle);
  551. }
  552. if (client != nullptr)
  553. {
  554. if (client->isActive())
  555. {
  556. // must not happen
  557. carla_safe_assert("client->isActive()", __FILE__, __LINE__);
  558. client->deactivate();
  559. }
  560. clearBuffers();
  561. delete client;
  562. client = nullptr;
  563. }
  564. if (name != nullptr)
  565. {
  566. delete[] name;
  567. name = nullptr;
  568. }
  569. if (filename != nullptr)
  570. {
  571. delete[] filename;
  572. filename = nullptr;
  573. }
  574. if (iconName != nullptr)
  575. {
  576. delete[] iconName;
  577. iconName = nullptr;
  578. }
  579. for (LinkedList<CustomData>::Itenerator it = custom.begin2(); it.valid(); it.next())
  580. {
  581. CustomData& customData(it.getValue(kCustomDataFallbackNC));
  582. //CARLA_SAFE_ASSERT_CONTINUE(customData.isValid());
  583. if (customData.type != nullptr)
  584. {
  585. delete[] customData.type;
  586. customData.type = nullptr;
  587. }
  588. else
  589. carla_safe_assert("customData.type != nullptr", __FILE__, __LINE__);
  590. if (customData.key != nullptr)
  591. {
  592. delete[] customData.key;
  593. customData.key = nullptr;
  594. }
  595. else
  596. carla_safe_assert("customData.key != nullptr", __FILE__, __LINE__);
  597. if (customData.value != nullptr)
  598. {
  599. delete[] customData.value;
  600. customData.value = nullptr;
  601. }
  602. else
  603. carla_safe_assert("customData.value != nullptr", __FILE__, __LINE__);
  604. }
  605. prog.clear();
  606. midiprog.clear();
  607. custom.clear();
  608. // MUST have been locked before
  609. masterMutex.unlock();
  610. singleMutex.unlock();
  611. CARLA_SAFE_ASSERT(uiLib == nullptr);
  612. if (lib != nullptr)
  613. libClose();
  614. }
  615. // -----------------------------------------------------------------------
  616. // Buffer functions
  617. void CarlaPlugin::ProtectedData::clearBuffers() noexcept
  618. {
  619. audioIn.clear();
  620. audioOut.clear();
  621. cvIn.clear();
  622. cvOut.clear();
  623. param.clear();
  624. event.clear();
  625. #ifndef BUILD_BRIDGE
  626. latency.clearBuffers();
  627. #endif
  628. }
  629. // -----------------------------------------------------------------------
  630. // Post-poned events
  631. void CarlaPlugin::ProtectedData::postponeRtEvent(const PluginPostRtEvent& rtEvent) noexcept
  632. {
  633. CARLA_SAFE_ASSERT_RETURN(rtEvent.type != kPluginPostRtEventNull,);
  634. postRtEvents.appendRT(rtEvent);
  635. }
  636. void CarlaPlugin::ProtectedData::postponeRtEvent(const PluginPostRtEventType type,
  637. const bool sendCallbackLater,
  638. const int32_t value1,
  639. const int32_t value2,
  640. const int32_t value3,
  641. const float valuef) noexcept
  642. {
  643. CARLA_SAFE_ASSERT_RETURN(type != kPluginPostRtEventNull,);
  644. PluginPostRtEvent rtEvent = { type, sendCallbackLater, value1, value2, value3, valuef };
  645. postRtEvents.appendRT(rtEvent);
  646. }
  647. // -----------------------------------------------------------------------
  648. // Library functions
  649. static LibCounter sLibCounter;
  650. const char* CarlaPlugin::ProtectedData::libError(const char* const fname) noexcept
  651. {
  652. return lib_error(fname);
  653. }
  654. bool CarlaPlugin::ProtectedData::libOpen(const char* const fname) noexcept
  655. {
  656. lib = sLibCounter.open(fname);
  657. return (lib != nullptr);
  658. }
  659. bool CarlaPlugin::ProtectedData::libClose() noexcept
  660. {
  661. const bool ret = sLibCounter.close(lib);
  662. lib = nullptr;
  663. return ret;
  664. }
  665. void CarlaPlugin::ProtectedData::setCanDeleteLib(const bool canDelete) noexcept
  666. {
  667. sLibCounter.setCanDelete(lib, canDelete);
  668. }
  669. bool CarlaPlugin::ProtectedData::uiLibOpen(const char* const fname, const bool canDelete) noexcept
  670. {
  671. uiLib = sLibCounter.open(fname, canDelete);
  672. return (uiLib != nullptr);
  673. }
  674. bool CarlaPlugin::ProtectedData::uiLibClose() noexcept
  675. {
  676. const bool ret = sLibCounter.close(uiLib);
  677. uiLib = nullptr;
  678. return ret;
  679. }
  680. // -----------------------------------------------------------------------
  681. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  682. void CarlaPlugin::ProtectedData::tryTransient() noexcept
  683. {
  684. if (engine->getOptions().frontendWinId != 0)
  685. transientTryCounter = 1;
  686. }
  687. #endif
  688. void CarlaPlugin::ProtectedData::updateParameterValues(CarlaPlugin* const plugin,
  689. const bool sendCallback,
  690. const bool sendOsc,
  691. const bool useDefault) noexcept
  692. {
  693. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback || useDefault,);
  694. for (uint32_t i=0; i < param.count; ++i)
  695. {
  696. const float value(param.ranges[i].getFixedValue(plugin->getParameterValue(i)));
  697. if (useDefault)
  698. param.ranges[i].def = value;
  699. if (useDefault) {
  700. engine->callback(sendCallback, sendOsc,
  701. ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED,
  702. id,
  703. static_cast<int>(i),
  704. 0, 0,
  705. value,
  706. nullptr);
  707. }
  708. engine->callback(sendCallback, sendOsc,
  709. ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
  710. id,
  711. static_cast<int>(i),
  712. 0, 0,
  713. value,
  714. nullptr);
  715. }
  716. }
  717. void CarlaPlugin::ProtectedData::updateDefaultParameterValues(CarlaPlugin* const plugin) noexcept
  718. {
  719. for (uint32_t i=0; i < param.count; ++i)
  720. param.ranges[i].def = param.ranges[i].getFixedValue(plugin->getParameterValue(i));
  721. }
  722. // -----------------------------------------------------------------------
  723. CARLA_BACKEND_END_NAMESPACE