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.

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