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.

935 lines
23KB

  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. cvSourcePorts = nullptr;
  146. #endif
  147. }
  148. void PluginEventData::initBuffers() const noexcept
  149. {
  150. if (portIn != nullptr)
  151. portIn->initBuffer();
  152. if (portOut != nullptr)
  153. portOut->initBuffer();
  154. }
  155. // -----------------------------------------------------------------------
  156. // PluginParameterData
  157. PluginParameterData::PluginParameterData() noexcept
  158. : count(0),
  159. data(nullptr),
  160. ranges(nullptr),
  161. special(nullptr) {}
  162. PluginParameterData::~PluginParameterData() noexcept
  163. {
  164. CARLA_SAFE_ASSERT_INT(count == 0, count);
  165. CARLA_SAFE_ASSERT(data == nullptr);
  166. CARLA_SAFE_ASSERT(ranges == nullptr);
  167. CARLA_SAFE_ASSERT(special == nullptr);
  168. }
  169. void PluginParameterData::createNew(const uint32_t newCount, const bool withSpecial)
  170. {
  171. CARLA_SAFE_ASSERT_INT(count == 0, count);
  172. CARLA_SAFE_ASSERT_RETURN(data == nullptr,);
  173. CARLA_SAFE_ASSERT_RETURN(ranges == nullptr,);
  174. CARLA_SAFE_ASSERT_RETURN(special == nullptr,);
  175. CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
  176. data = new ParameterData[newCount];
  177. carla_zeroStructs(data, newCount);
  178. for (uint32_t i=0; i < newCount; ++i)
  179. {
  180. data[i].index = PARAMETER_NULL;
  181. data[i].rindex = PARAMETER_NULL;
  182. data[i].mappedControlIndex = CONTROL_INDEX_NONE;
  183. data[i].mappedMinimum = -1.0f;
  184. data[i].mappedMaximum = 1.0f;
  185. }
  186. ranges = new ParameterRanges[newCount];
  187. carla_zeroStructs(ranges, newCount);
  188. if (withSpecial)
  189. {
  190. special = new SpecialParameterType[newCount];
  191. carla_zeroStructs(special, newCount);
  192. }
  193. count = newCount;
  194. }
  195. void PluginParameterData::clear() noexcept
  196. {
  197. if (data != nullptr)
  198. {
  199. delete[] data;
  200. data = nullptr;
  201. }
  202. if (ranges != nullptr)
  203. {
  204. delete[] ranges;
  205. ranges = nullptr;
  206. }
  207. if (special != nullptr)
  208. {
  209. delete[] special;
  210. special = nullptr;
  211. }
  212. count = 0;
  213. }
  214. float PluginParameterData::getFixedValue(const uint32_t parameterId, float value) const noexcept
  215. {
  216. CARLA_SAFE_ASSERT_RETURN(parameterId < count, 0.0f);
  217. const uint paramHints (data[parameterId].hints);
  218. const ParameterRanges& paramRanges(ranges[parameterId]);
  219. // if boolean, return either min or max
  220. if (paramHints & PARAMETER_IS_BOOLEAN)
  221. {
  222. const float middlePoint = paramRanges.min + (paramRanges.max-paramRanges.min)/2.0f;
  223. return value >= middlePoint ? paramRanges.max : paramRanges.min;
  224. }
  225. // if integer, round first
  226. if (paramHints & PARAMETER_IS_INTEGER)
  227. return paramRanges.getFixedValue(std::round(value));
  228. // normal mode
  229. return paramRanges.getFixedValue(value);
  230. }
  231. // copied from ParameterRanges::getUnnormalizedValue
  232. static float _getUnnormalizedValue(const float min, const float max, const float value) noexcept
  233. {
  234. if (value <= 0.0f)
  235. return min;
  236. if (value >= 1.0f)
  237. return max;
  238. return value * (max - min) + min;
  239. }
  240. // copied from ParameterRanges::getUnnormalizedLogValue
  241. static float _getUnnormalizedLogValue(const float min, const float max, const float value) noexcept
  242. {
  243. if (value <= 0.0f)
  244. return min;
  245. if (value >= 1.0f)
  246. return max;
  247. float rmin = min;
  248. if (std::abs(min) < std::numeric_limits<float>::epsilon())
  249. rmin = 0.00001f;
  250. return rmin * std::pow(max/rmin, value);
  251. }
  252. float PluginParameterData::getFinalUnnormalizedValue(const uint32_t parameterId, float value) const noexcept
  253. {
  254. float min, max;
  255. if (data[parameterId].mappedControlIndex != CONTROL_INDEX_CV
  256. && (data[parameterId].hints & PARAMETER_MAPPED_RANGES_SET) != 0x0)
  257. {
  258. min = data[parameterId].mappedMinimum;
  259. max = data[parameterId].mappedMaximum;
  260. }
  261. else
  262. {
  263. min = ranges[parameterId].min;
  264. max = ranges[parameterId].max;
  265. }
  266. if (data[parameterId].hints & PARAMETER_IS_BOOLEAN)
  267. {
  268. value = (value < 0.5f) ? min : max;
  269. }
  270. else
  271. {
  272. if (data[parameterId].hints & PARAMETER_IS_LOGARITHMIC)
  273. value = _getUnnormalizedLogValue(min, max, value);
  274. else
  275. value = _getUnnormalizedValue(min, max, value);
  276. if (data[parameterId].hints & PARAMETER_IS_INTEGER)
  277. value = std::rint(value);
  278. }
  279. return value;
  280. }
  281. // -----------------------------------------------------------------------
  282. // PluginProgramData
  283. PluginProgramData::PluginProgramData() noexcept
  284. : count(0),
  285. current(-1),
  286. names(nullptr) {}
  287. PluginProgramData::~PluginProgramData() noexcept
  288. {
  289. CARLA_SAFE_ASSERT_INT(count == 0, count);
  290. CARLA_SAFE_ASSERT_INT(current == -1, current);
  291. CARLA_SAFE_ASSERT(names == nullptr);
  292. }
  293. void PluginProgramData::createNew(const uint32_t newCount)
  294. {
  295. CARLA_SAFE_ASSERT_INT(count == 0, count);
  296. CARLA_SAFE_ASSERT_INT(current == -1, current);
  297. CARLA_SAFE_ASSERT_RETURN(names == nullptr,);
  298. CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
  299. names = new ProgramName[newCount];
  300. carla_zeroStructs(names, newCount);
  301. count = newCount;
  302. current = -1;
  303. }
  304. void PluginProgramData::clear() noexcept
  305. {
  306. if (names != nullptr)
  307. {
  308. for (uint32_t i=0; i < count; ++i)
  309. {
  310. if (names[i] != nullptr)
  311. {
  312. delete[] names[i];
  313. names[i] = nullptr;
  314. }
  315. }
  316. delete[] names;
  317. names = nullptr;
  318. }
  319. count = 0;
  320. current = -1;
  321. }
  322. // -----------------------------------------------------------------------
  323. // PluginMidiProgramData
  324. PluginMidiProgramData::PluginMidiProgramData() noexcept
  325. : count(0),
  326. current(-1),
  327. data(nullptr) {}
  328. PluginMidiProgramData::~PluginMidiProgramData() noexcept
  329. {
  330. CARLA_SAFE_ASSERT_INT(count == 0, count);
  331. CARLA_SAFE_ASSERT_INT(current == -1, current);
  332. CARLA_SAFE_ASSERT(data == nullptr);
  333. }
  334. void PluginMidiProgramData::createNew(const uint32_t newCount)
  335. {
  336. CARLA_SAFE_ASSERT_INT(count == 0, count);
  337. CARLA_SAFE_ASSERT_INT(current == -1, current);
  338. CARLA_SAFE_ASSERT_RETURN(data == nullptr,);
  339. CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
  340. data = new MidiProgramData[newCount];
  341. carla_zeroStructs(data, newCount);
  342. count = newCount;
  343. current = -1;
  344. }
  345. void PluginMidiProgramData::clear() noexcept
  346. {
  347. if (data != nullptr)
  348. {
  349. for (uint32_t i=0; i < count; ++i)
  350. {
  351. if (data[i].name != nullptr)
  352. {
  353. delete[] data[i].name;
  354. data[i].name = nullptr;
  355. }
  356. }
  357. delete[] data;
  358. data = nullptr;
  359. }
  360. count = 0;
  361. current = -1;
  362. }
  363. const MidiProgramData& PluginMidiProgramData::getCurrent() const noexcept
  364. {
  365. CARLA_SAFE_ASSERT_RETURN(current >= 0 && current < static_cast<int32_t>(count), kMidiProgramDataNull);
  366. return data[current];
  367. }
  368. // -----------------------------------------------------------------------
  369. // ProtectedData::ExternalNotes
  370. CarlaPlugin::ProtectedData::ExternalNotes::ExternalNotes() noexcept
  371. : mutex(),
  372. dataPool(32, 152),
  373. data(dataPool) {}
  374. CarlaPlugin::ProtectedData::ExternalNotes::~ExternalNotes() noexcept
  375. {
  376. clear();
  377. }
  378. void CarlaPlugin::ProtectedData::ExternalNotes::appendNonRT(const ExternalMidiNote& note) noexcept
  379. {
  380. mutex.lock();
  381. data.append_sleepy(note);
  382. mutex.unlock();
  383. }
  384. void CarlaPlugin::ProtectedData::ExternalNotes::clear() noexcept
  385. {
  386. mutex.lock();
  387. data.clear();
  388. mutex.unlock();
  389. }
  390. // -----------------------------------------------------------------------
  391. // ProtectedData::Latency
  392. CarlaPlugin::ProtectedData::Latency::Latency() noexcept
  393. #ifdef BUILD_BRIDGE
  394. : frames(0) {}
  395. #else
  396. : frames(0),
  397. channels(0),
  398. buffers(nullptr) {}
  399. #endif
  400. #ifndef BUILD_BRIDGE
  401. CarlaPlugin::ProtectedData::Latency::~Latency() noexcept
  402. {
  403. clearBuffers();
  404. }
  405. void CarlaPlugin::ProtectedData::Latency::clearBuffers() noexcept
  406. {
  407. if (buffers != nullptr)
  408. {
  409. for (uint32_t i=0; i < channels; ++i)
  410. {
  411. CARLA_SAFE_ASSERT_CONTINUE(buffers[i] != nullptr);
  412. delete[] buffers[i];
  413. buffers[i] = nullptr;
  414. }
  415. delete[] buffers;
  416. buffers = nullptr;
  417. }
  418. channels = 0;
  419. frames = 0;
  420. }
  421. void CarlaPlugin::ProtectedData::Latency::recreateBuffers(const uint32_t newChannels, const uint32_t newFrames)
  422. {
  423. CARLA_SAFE_ASSERT_RETURN(channels != newChannels || frames != newFrames,);
  424. const bool retrieveOldBuffer = (channels == newChannels && channels > 0 && frames > 0 && newFrames > 0);
  425. float** const oldBuffers = buffers;
  426. const uint32_t oldFrames = frames;
  427. channels = newChannels;
  428. frames = newFrames;
  429. if (channels > 0 && frames > 0)
  430. {
  431. buffers = new float*[channels];
  432. for (uint32_t i=0; i < channels; ++i)
  433. {
  434. buffers[i] = new float[frames];
  435. if (retrieveOldBuffer)
  436. {
  437. if (oldFrames > frames)
  438. {
  439. const uint32_t diff = oldFrames - frames;
  440. carla_copyFloats(buffers[i], oldBuffers[i] + diff, frames);
  441. }
  442. else
  443. {
  444. const uint32_t diff = frames - oldFrames;
  445. carla_zeroFloats(buffers[i], diff);
  446. carla_copyFloats(buffers[i] + diff, oldBuffers[i], oldFrames);
  447. }
  448. }
  449. else
  450. {
  451. carla_zeroFloats(buffers[i], frames);
  452. }
  453. }
  454. }
  455. else
  456. {
  457. buffers = nullptr;
  458. }
  459. // delete old buffer
  460. if (oldBuffers != nullptr)
  461. {
  462. for (uint32_t i=0; i < channels; ++i)
  463. {
  464. CARLA_SAFE_ASSERT_CONTINUE(oldBuffers[i] != nullptr);
  465. delete[] oldBuffers[i];
  466. oldBuffers[i] = nullptr;
  467. }
  468. delete[] oldBuffers;
  469. }
  470. }
  471. #endif
  472. // -----------------------------------------------------------------------
  473. // ProtectedData::PostRtEvents
  474. CarlaPlugin::ProtectedData::PostRtEvents::PostRtEvents() noexcept
  475. : dataPool(128, 128),
  476. dataPendingRT(dataPool),
  477. data(dataPool),
  478. dataMutex(),
  479. dataPendingMutex() {}
  480. CarlaPlugin::ProtectedData::PostRtEvents::~PostRtEvents() noexcept
  481. {
  482. dataMutex.lock();
  483. data.clear();
  484. dataMutex.unlock();
  485. dataPendingMutex.lock();
  486. dataPendingRT.clear();
  487. dataPendingMutex.unlock();
  488. }
  489. void CarlaPlugin::ProtectedData::PostRtEvents::appendRT(const PluginPostRtEvent& e) noexcept
  490. {
  491. CARLA_SAFE_ASSERT_INT2_RETURN(dataPendingMutex.tryLock(), e.type, e.value1,);
  492. dataPendingRT.append(e);
  493. dataPendingMutex.unlock();
  494. }
  495. void CarlaPlugin::ProtectedData::PostRtEvents::trySplice() noexcept
  496. {
  497. const CarlaMutexTryLocker cmtl(dataPendingMutex);
  498. if (cmtl.wasLocked() && dataPendingRT.count() > 0 && dataMutex.tryLock())
  499. {
  500. dataPendingRT.moveTo(data, true);
  501. dataMutex.unlock();
  502. }
  503. }
  504. void CarlaPlugin::ProtectedData::PostRtEvents::clearData() noexcept
  505. {
  506. const bool tryLockOk(dataMutex.tryLock());
  507. CARLA_SAFE_ASSERT(! tryLockOk);
  508. data.clear();
  509. if (tryLockOk)
  510. dataMutex.unlock();
  511. }
  512. // -----------------------------------------------------------------------
  513. // ProtectedData::PostUiEvents
  514. CarlaPlugin::ProtectedData::PostUiEvents::PostUiEvents() noexcept
  515. : mutex(),
  516. data() {}
  517. CarlaPlugin::ProtectedData::PostUiEvents::~PostUiEvents() noexcept
  518. {
  519. clear();
  520. }
  521. void CarlaPlugin::ProtectedData::PostUiEvents::append(const PluginPostRtEvent& e) noexcept
  522. {
  523. mutex.lock();
  524. data.append(e);
  525. mutex.unlock();
  526. }
  527. void CarlaPlugin::ProtectedData::PostUiEvents::clear() noexcept
  528. {
  529. mutex.lock();
  530. data.clear();
  531. mutex.unlock();
  532. }
  533. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  534. // -----------------------------------------------------------------------
  535. // ProtectedData::PostProc
  536. CarlaPlugin::ProtectedData::PostProc::PostProc() noexcept
  537. : dryWet(1.0f),
  538. volume(1.0f),
  539. balanceLeft(-1.0f),
  540. balanceRight(1.0f),
  541. panning(0.0f) {}
  542. #endif
  543. // -----------------------------------------------------------------------
  544. CarlaPlugin::ProtectedData::ProtectedData(CarlaEngine* const eng, const uint idx) noexcept
  545. : engine(eng),
  546. client(nullptr),
  547. id(idx),
  548. hints(0x0),
  549. options(0x0),
  550. nodeId(0),
  551. active(false),
  552. enabled(false),
  553. needsReset(false),
  554. engineBridged(eng->getType() == kEngineTypeBridge),
  555. enginePlugin(eng->getType() == kEngineTypePlugin),
  556. lib(nullptr),
  557. uiLib(nullptr),
  558. ctrlChannel(0),
  559. extraHints(0x0),
  560. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  561. transientTryCounter(0),
  562. transientFirstTry(true),
  563. #endif
  564. name(nullptr),
  565. filename(nullptr),
  566. iconName(nullptr),
  567. audioIn(),
  568. audioOut(),
  569. cvIn(),
  570. cvOut(),
  571. event(),
  572. param(),
  573. prog(),
  574. midiprog(),
  575. custom(),
  576. masterMutex(),
  577. singleMutex(),
  578. stateSave(),
  579. extNotes(),
  580. latency(),
  581. postRtEvents(),
  582. postUiEvents()
  583. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  584. , postProc()
  585. #endif
  586. {}
  587. CarlaPlugin::ProtectedData::~ProtectedData() noexcept
  588. {
  589. CARLA_SAFE_ASSERT(! (active && needsReset));
  590. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  591. CARLA_SAFE_ASSERT(transientTryCounter == 0);
  592. #endif
  593. {
  594. // mutex MUST have been locked before
  595. const bool lockMaster(masterMutex.tryLock());
  596. const bool lockSingle(singleMutex.tryLock());
  597. CARLA_SAFE_ASSERT(! lockMaster);
  598. CARLA_SAFE_ASSERT(! lockSingle);
  599. }
  600. if (client != nullptr)
  601. {
  602. if (client->isActive())
  603. {
  604. // must not happen
  605. carla_safe_assert("client->isActive()", __FILE__, __LINE__);
  606. client->deactivate();
  607. }
  608. clearBuffers();
  609. delete client;
  610. client = nullptr;
  611. }
  612. if (name != nullptr)
  613. {
  614. delete[] name;
  615. name = nullptr;
  616. }
  617. if (filename != nullptr)
  618. {
  619. delete[] filename;
  620. filename = nullptr;
  621. }
  622. if (iconName != nullptr)
  623. {
  624. delete[] iconName;
  625. iconName = nullptr;
  626. }
  627. for (LinkedList<CustomData>::Itenerator it = custom.begin2(); it.valid(); it.next())
  628. {
  629. CustomData& customData(it.getValue(kCustomDataFallbackNC));
  630. //CARLA_SAFE_ASSERT_CONTINUE(customData.isValid());
  631. if (customData.type != nullptr)
  632. {
  633. delete[] customData.type;
  634. customData.type = nullptr;
  635. }
  636. else
  637. carla_safe_assert("customData.type != nullptr", __FILE__, __LINE__);
  638. if (customData.key != nullptr)
  639. {
  640. delete[] customData.key;
  641. customData.key = nullptr;
  642. }
  643. else
  644. carla_safe_assert("customData.key != nullptr", __FILE__, __LINE__);
  645. if (customData.value != nullptr)
  646. {
  647. delete[] customData.value;
  648. customData.value = nullptr;
  649. }
  650. else
  651. carla_safe_assert("customData.value != nullptr", __FILE__, __LINE__);
  652. }
  653. prog.clear();
  654. midiprog.clear();
  655. custom.clear();
  656. // MUST have been locked before
  657. masterMutex.unlock();
  658. singleMutex.unlock();
  659. CARLA_SAFE_ASSERT(uiLib == nullptr);
  660. if (lib != nullptr)
  661. libClose();
  662. }
  663. // -----------------------------------------------------------------------
  664. // Buffer functions
  665. void CarlaPlugin::ProtectedData::clearBuffers() noexcept
  666. {
  667. audioIn.clear();
  668. audioOut.clear();
  669. cvIn.clear();
  670. cvOut.clear();
  671. param.clear();
  672. event.clear();
  673. #ifndef BUILD_BRIDGE
  674. latency.clearBuffers();
  675. #endif
  676. }
  677. // -----------------------------------------------------------------------
  678. // Post-poned events
  679. void CarlaPlugin::ProtectedData::postponeRtEvent(const PluginPostRtEvent& rtEvent) noexcept
  680. {
  681. CARLA_SAFE_ASSERT_RETURN(rtEvent.type != kPluginPostRtEventNull,);
  682. postRtEvents.appendRT(rtEvent);
  683. }
  684. void CarlaPlugin::ProtectedData::postponeRtEvent(const PluginPostRtEventType type,
  685. const bool sendCallbackLater,
  686. const int32_t value1,
  687. const int32_t value2,
  688. const int32_t value3,
  689. const float valuef) noexcept
  690. {
  691. CARLA_SAFE_ASSERT_RETURN(type != kPluginPostRtEventNull,);
  692. PluginPostRtEvent rtEvent = { type, sendCallbackLater, value1, value2, value3, valuef };
  693. postRtEvents.appendRT(rtEvent);
  694. }
  695. // -----------------------------------------------------------------------
  696. // Library functions
  697. static LibCounter sLibCounter;
  698. const char* CarlaPlugin::ProtectedData::libError(const char* const fname) noexcept
  699. {
  700. return lib_error(fname);
  701. }
  702. bool CarlaPlugin::ProtectedData::libOpen(const char* const fname) noexcept
  703. {
  704. lib = sLibCounter.open(fname);
  705. return (lib != nullptr);
  706. }
  707. bool CarlaPlugin::ProtectedData::libClose() noexcept
  708. {
  709. const bool ret = sLibCounter.close(lib);
  710. lib = nullptr;
  711. return ret;
  712. }
  713. void CarlaPlugin::ProtectedData::setCanDeleteLib(const bool canDelete) noexcept
  714. {
  715. sLibCounter.setCanDelete(lib, canDelete);
  716. }
  717. bool CarlaPlugin::ProtectedData::uiLibOpen(const char* const fname, const bool canDelete) noexcept
  718. {
  719. uiLib = sLibCounter.open(fname, canDelete);
  720. return (uiLib != nullptr);
  721. }
  722. bool CarlaPlugin::ProtectedData::uiLibClose() noexcept
  723. {
  724. const bool ret = sLibCounter.close(uiLib);
  725. uiLib = nullptr;
  726. return ret;
  727. }
  728. // -----------------------------------------------------------------------
  729. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  730. void CarlaPlugin::ProtectedData::tryTransient() noexcept
  731. {
  732. if (engine->getOptions().frontendWinId != 0)
  733. transientTryCounter = 1;
  734. }
  735. #endif
  736. void CarlaPlugin::ProtectedData::updateParameterValues(CarlaPlugin* const plugin,
  737. const bool sendCallback,
  738. const bool sendOsc,
  739. const bool useDefault) noexcept
  740. {
  741. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback || useDefault,);
  742. for (uint32_t i=0; i < param.count; ++i)
  743. {
  744. const float value(param.ranges[i].getFixedValue(plugin->getParameterValue(i)));
  745. if (useDefault)
  746. param.ranges[i].def = value;
  747. if (useDefault) {
  748. engine->callback(sendCallback, sendOsc,
  749. ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED,
  750. id,
  751. static_cast<int>(i),
  752. 0, 0,
  753. value,
  754. nullptr);
  755. }
  756. engine->callback(sendCallback, sendOsc,
  757. ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
  758. id,
  759. static_cast<int>(i),
  760. 0, 0,
  761. value,
  762. nullptr);
  763. }
  764. }
  765. void CarlaPlugin::ProtectedData::updateDefaultParameterValues(CarlaPlugin* const plugin) noexcept
  766. {
  767. for (uint32_t i=0; i < param.count; ++i)
  768. param.ranges[i].def = param.ranges[i].getFixedValue(plugin->getParameterValue(i));
  769. }
  770. // -----------------------------------------------------------------------
  771. CARLA_BACKEND_END_NAMESPACE