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.

CarlaPluginInternal.cpp 18KB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  1. /*
  2. * Carla Plugin
  3. * Copyright (C) 2011-2014 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 const CustomData kCustomDataFallback = { nullptr, nullptr, nullptr };
  26. static /* */ CustomData kCustomDataFallbackNC = { nullptr, nullptr, nullptr };
  27. // -----------------------------------------------------------------------
  28. // PluginAudioData
  29. PluginAudioData::PluginAudioData() noexcept
  30. : count(0),
  31. ports(nullptr) {}
  32. PluginAudioData::~PluginAudioData() noexcept
  33. {
  34. CARLA_SAFE_ASSERT_INT(count == 0, count);
  35. CARLA_SAFE_ASSERT(ports == nullptr);
  36. }
  37. void PluginAudioData::createNew(const uint32_t newCount)
  38. {
  39. CARLA_SAFE_ASSERT_INT(count == 0, count);
  40. CARLA_SAFE_ASSERT_RETURN(ports == nullptr,);
  41. CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
  42. ports = new PluginAudioPort[newCount];
  43. carla_zeroStruct(ports, newCount);
  44. count = newCount;
  45. }
  46. void PluginAudioData::clear() noexcept
  47. {
  48. if (ports != nullptr)
  49. {
  50. for (uint32_t i=0; i < count; ++i)
  51. {
  52. if (ports[i].port != nullptr)
  53. {
  54. delete ports[i].port;
  55. ports[i].port = nullptr;
  56. }
  57. }
  58. delete[] ports;
  59. ports = nullptr;
  60. }
  61. count = 0;
  62. }
  63. void PluginAudioData::initBuffers() const noexcept
  64. {
  65. for (uint32_t i=0; i < count; ++i)
  66. {
  67. if (ports[i].port != nullptr)
  68. ports[i].port->initBuffer();
  69. }
  70. }
  71. // -----------------------------------------------------------------------
  72. // PluginCVData
  73. PluginCVData::PluginCVData() noexcept
  74. : count(0),
  75. ports(nullptr) {}
  76. PluginCVData::~PluginCVData() noexcept
  77. {
  78. CARLA_SAFE_ASSERT_INT(count == 0, count);
  79. CARLA_SAFE_ASSERT(ports == nullptr);
  80. }
  81. void PluginCVData::createNew(const uint32_t newCount)
  82. {
  83. CARLA_SAFE_ASSERT_INT(count == 0, count);
  84. CARLA_SAFE_ASSERT_RETURN(ports == nullptr,);
  85. CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
  86. ports = new PluginCVPort[newCount];
  87. carla_zeroStruct(ports, newCount);
  88. count = newCount;
  89. }
  90. void PluginCVData::clear() noexcept
  91. {
  92. if (ports != nullptr)
  93. {
  94. for (uint32_t i=0; i < count; ++i)
  95. {
  96. if (ports[i].port != nullptr)
  97. {
  98. delete ports[i].port;
  99. ports[i].port = nullptr;
  100. }
  101. }
  102. delete[] ports;
  103. ports = nullptr;
  104. }
  105. count = 0;
  106. }
  107. void PluginCVData::initBuffers() const noexcept
  108. {
  109. for (uint32_t i=0; i < count; ++i)
  110. {
  111. if (ports[i].port != nullptr)
  112. ports[i].port->initBuffer();
  113. }
  114. }
  115. // -----------------------------------------------------------------------
  116. // PluginEventData
  117. PluginEventData::PluginEventData() noexcept
  118. : portIn(nullptr),
  119. portOut(nullptr) {}
  120. PluginEventData::~PluginEventData() noexcept
  121. {
  122. CARLA_SAFE_ASSERT(portIn == nullptr);
  123. CARLA_SAFE_ASSERT(portOut == nullptr);
  124. }
  125. void PluginEventData::clear() noexcept
  126. {
  127. if (portIn != nullptr)
  128. {
  129. delete portIn;
  130. portIn = nullptr;
  131. }
  132. if (portOut != nullptr)
  133. {
  134. delete portOut;
  135. portOut = nullptr;
  136. }
  137. }
  138. void PluginEventData::initBuffers() const noexcept
  139. {
  140. if (portIn != nullptr)
  141. portIn->initBuffer();
  142. if (portOut != nullptr)
  143. portOut->initBuffer();
  144. }
  145. // -----------------------------------------------------------------------
  146. // PluginParameterData
  147. PluginParameterData::PluginParameterData() noexcept
  148. : count(0),
  149. data(nullptr),
  150. ranges(nullptr),
  151. special(nullptr) {}
  152. PluginParameterData::~PluginParameterData() noexcept
  153. {
  154. CARLA_SAFE_ASSERT_INT(count == 0, count);
  155. CARLA_SAFE_ASSERT(data == nullptr);
  156. CARLA_SAFE_ASSERT(ranges == nullptr);
  157. CARLA_SAFE_ASSERT(special == nullptr);
  158. }
  159. void PluginParameterData::createNew(const uint32_t newCount, const bool withSpecial)
  160. {
  161. CARLA_SAFE_ASSERT_INT(count == 0, count);
  162. CARLA_SAFE_ASSERT_RETURN(data == nullptr,);
  163. CARLA_SAFE_ASSERT_RETURN(ranges == nullptr,);
  164. CARLA_SAFE_ASSERT_RETURN(special == nullptr,);
  165. CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
  166. data = new ParameterData[newCount];
  167. carla_zeroStruct(data, newCount);
  168. for (uint32_t i=0; i < newCount; ++i)
  169. {
  170. data[i].index = PARAMETER_NULL;
  171. data[i].rindex = PARAMETER_NULL;
  172. data[i].midiCC = -1;
  173. }
  174. ranges = new ParameterRanges[newCount];
  175. carla_zeroStruct(ranges, newCount);
  176. if (withSpecial)
  177. {
  178. special = new SpecialParameterType[newCount];
  179. carla_zeroStruct(special, newCount);
  180. }
  181. count = newCount;
  182. }
  183. void PluginParameterData::clear() noexcept
  184. {
  185. if (data != nullptr)
  186. {
  187. delete[] data;
  188. data = nullptr;
  189. }
  190. if (ranges != nullptr)
  191. {
  192. delete[] ranges;
  193. ranges = nullptr;
  194. }
  195. if (special != nullptr)
  196. {
  197. delete[] special;
  198. special = nullptr;
  199. }
  200. count = 0;
  201. }
  202. float PluginParameterData::getFixedValue(const uint32_t parameterId, const float& value) const noexcept
  203. {
  204. CARLA_SAFE_ASSERT_RETURN(parameterId < count, 0.0f);
  205. return ranges[parameterId].getFixedValue(value);
  206. }
  207. // -----------------------------------------------------------------------
  208. // PluginProgramData
  209. PluginProgramData::PluginProgramData() noexcept
  210. : count(0),
  211. current(-1),
  212. names(nullptr) {}
  213. PluginProgramData::~PluginProgramData() noexcept
  214. {
  215. CARLA_SAFE_ASSERT_INT(count == 0, count);
  216. CARLA_SAFE_ASSERT_INT(current == -1, current);
  217. CARLA_SAFE_ASSERT(names == nullptr);
  218. }
  219. void PluginProgramData::createNew(const uint32_t newCount)
  220. {
  221. CARLA_SAFE_ASSERT_INT(count == 0, count);
  222. CARLA_SAFE_ASSERT_INT(current == -1, current);
  223. CARLA_SAFE_ASSERT_RETURN(names == nullptr,);
  224. CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
  225. names = new ProgramName[newCount];
  226. carla_zeroStruct(names, newCount);
  227. count = newCount;
  228. current = -1;
  229. }
  230. void PluginProgramData::clear() noexcept
  231. {
  232. if (names != nullptr)
  233. {
  234. for (uint32_t i=0; i < count; ++i)
  235. {
  236. if (names[i] != nullptr)
  237. {
  238. delete[] names[i];
  239. names[i] = nullptr;
  240. }
  241. }
  242. delete[] names;
  243. names = nullptr;
  244. }
  245. count = 0;
  246. current = -1;
  247. }
  248. // -----------------------------------------------------------------------
  249. // PluginMidiProgramData
  250. PluginMidiProgramData::PluginMidiProgramData() noexcept
  251. : count(0),
  252. current(-1),
  253. data(nullptr) {}
  254. PluginMidiProgramData::~PluginMidiProgramData() noexcept
  255. {
  256. CARLA_SAFE_ASSERT_INT(count == 0, count);
  257. CARLA_SAFE_ASSERT_INT(current == -1, current);
  258. CARLA_SAFE_ASSERT(data == nullptr);
  259. }
  260. void PluginMidiProgramData::createNew(const uint32_t newCount)
  261. {
  262. CARLA_SAFE_ASSERT_INT(count == 0, count);
  263. CARLA_SAFE_ASSERT_INT(current == -1, current);
  264. CARLA_SAFE_ASSERT_RETURN(data == nullptr,);
  265. CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
  266. data = new MidiProgramData[newCount];
  267. carla_zeroStruct(data, newCount);
  268. count = newCount;
  269. current = -1;
  270. }
  271. void PluginMidiProgramData::clear() noexcept
  272. {
  273. if (data != nullptr)
  274. {
  275. for (uint32_t i=0; i < count; ++i)
  276. {
  277. if (data[i].name != nullptr)
  278. {
  279. delete[] data[i].name;
  280. data[i].name = nullptr;
  281. }
  282. }
  283. delete[] data;
  284. data = nullptr;
  285. }
  286. count = 0;
  287. current = -1;
  288. }
  289. const MidiProgramData& PluginMidiProgramData::getCurrent() const noexcept
  290. {
  291. CARLA_SAFE_ASSERT_RETURN(current >= 0 && current < static_cast<int32_t>(count), kMidiProgramDataNull);
  292. return data[current];
  293. }
  294. // -----------------------------------------------------------------------
  295. // ProtectedData::ExternalNotes
  296. CarlaPlugin::ProtectedData::ExternalNotes::ExternalNotes() noexcept
  297. : mutex(),
  298. dataPool(32, 152),
  299. data(dataPool) {}
  300. CarlaPlugin::ProtectedData::ExternalNotes::~ExternalNotes() noexcept
  301. {
  302. clear();
  303. }
  304. void CarlaPlugin::ProtectedData::ExternalNotes::appendNonRT(const ExternalMidiNote& note) noexcept
  305. {
  306. mutex.lock();
  307. data.append_sleepy(note);
  308. mutex.unlock();
  309. }
  310. void CarlaPlugin::ProtectedData::ExternalNotes::clear() noexcept
  311. {
  312. mutex.lock();
  313. data.clear();
  314. mutex.unlock();
  315. }
  316. // -----------------------------------------------------------------------
  317. // ProtectedData::Latency
  318. CarlaPlugin::ProtectedData::Latency::Latency() noexcept
  319. : channels(0),
  320. frames(0),
  321. buffers(nullptr) {}
  322. CarlaPlugin::ProtectedData::Latency::~Latency() noexcept
  323. {
  324. clearBuffers();
  325. }
  326. void CarlaPlugin::ProtectedData::Latency::clearBuffers() noexcept
  327. {
  328. if (buffers != nullptr)
  329. {
  330. for (uint32_t i=0; i < channels; ++i)
  331. {
  332. CARLA_SAFE_ASSERT_CONTINUE(buffers[i] != nullptr);
  333. delete[] buffers[i];
  334. buffers[i] = nullptr;
  335. }
  336. delete[] buffers;
  337. buffers = nullptr;
  338. }
  339. channels = 0;
  340. frames = 0;
  341. }
  342. void CarlaPlugin::ProtectedData::Latency::recreateBuffers(const uint32_t newChannels, const uint32_t newFrames)
  343. {
  344. CARLA_SAFE_ASSERT_RETURN(channels != newChannels || frames != newFrames,);
  345. // delete old buffer
  346. if (buffers != nullptr)
  347. {
  348. for (uint32_t i=0; i < channels; ++i)
  349. {
  350. CARLA_SAFE_ASSERT_CONTINUE(buffers[i] != nullptr);
  351. delete[] buffers[i];
  352. buffers[i] = nullptr;
  353. }
  354. delete[] buffers;
  355. buffers = nullptr;
  356. }
  357. channels = newChannels;
  358. frames = newFrames;
  359. if (channels > 0 && frames > 0)
  360. {
  361. buffers = new float*[channels];
  362. for (uint32_t i=0; i < channels; ++i)
  363. {
  364. buffers[i] = new float[frames];
  365. FloatVectorOperations::clear(buffers[i], static_cast<int>(frames));
  366. }
  367. }
  368. }
  369. // -----------------------------------------------------------------------
  370. // ProtectedData::PostRtEvents
  371. CarlaPlugin::ProtectedData::PostRtEvents::PostRtEvents() noexcept
  372. : mutex(),
  373. dataPool(128, 128),
  374. data(dataPool),
  375. dataPendingRT(dataPool) {}
  376. CarlaPlugin::ProtectedData::PostRtEvents::~PostRtEvents() noexcept
  377. {
  378. clear();
  379. }
  380. void CarlaPlugin::ProtectedData::PostRtEvents::appendRT(const PluginPostRtEvent& e) noexcept
  381. {
  382. dataPendingRT.append(e);
  383. }
  384. void CarlaPlugin::ProtectedData::PostRtEvents::trySplice() noexcept
  385. {
  386. if (mutex.tryLock())
  387. {
  388. if (dataPendingRT.count() > 0)
  389. dataPendingRT.moveTo(data, true);
  390. mutex.unlock();
  391. }
  392. }
  393. void CarlaPlugin::ProtectedData::PostRtEvents::clear() noexcept
  394. {
  395. mutex.lock();
  396. data.clear();
  397. dataPendingRT.clear();
  398. mutex.unlock();
  399. }
  400. // -----------------------------------------------------------------------
  401. // ProtectedData::PostUiEvents
  402. CarlaPlugin::ProtectedData::PostUiEvents::PostUiEvents() noexcept
  403. : mutex(),
  404. data() {}
  405. CarlaPlugin::ProtectedData::PostUiEvents::~PostUiEvents() noexcept
  406. {
  407. clear();
  408. }
  409. void CarlaPlugin::ProtectedData::PostUiEvents::append(const PluginPostRtEvent& e) noexcept
  410. {
  411. mutex.lock();
  412. data.append(e);
  413. mutex.unlock();
  414. }
  415. void CarlaPlugin::ProtectedData::PostUiEvents::clear() noexcept
  416. {
  417. mutex.lock();
  418. data.clear();
  419. mutex.unlock();
  420. }
  421. #ifndef BUILD_BRIDGE
  422. // -----------------------------------------------------------------------
  423. // ProtectedData::PostProc
  424. CarlaPlugin::ProtectedData::PostProc::PostProc() noexcept
  425. : dryWet(1.0f),
  426. volume(1.0f),
  427. balanceLeft(-1.0f),
  428. balanceRight(1.0f),
  429. panning(0.0f) {}
  430. #endif
  431. // -----------------------------------------------------------------------
  432. CarlaPlugin::ProtectedData::ProtectedData(CarlaEngine* const eng, const uint idx) noexcept
  433. : engine(eng),
  434. client(nullptr),
  435. id(idx),
  436. hints(0x0),
  437. options(0x0),
  438. nodeId(0),
  439. active(false),
  440. enabled(false),
  441. needsReset(false),
  442. lib(nullptr),
  443. uiLib(nullptr),
  444. ctrlChannel(0),
  445. extraHints(0x0),
  446. transientTryCounter(0),
  447. name(nullptr),
  448. filename(nullptr),
  449. iconName(nullptr),
  450. audioIn(),
  451. audioOut(),
  452. cvIn(),
  453. cvOut(),
  454. event(),
  455. param(),
  456. prog(),
  457. midiprog(),
  458. custom(),
  459. masterMutex(),
  460. singleMutex(),
  461. stateSave(),
  462. extNotes(),
  463. latency(),
  464. postRtEvents(),
  465. postUiEvents(),
  466. #ifndef BUILD_BRIDGE
  467. postProc(),
  468. #endif
  469. leakDetector_ProtectedData() {}
  470. CarlaPlugin::ProtectedData::~ProtectedData() noexcept
  471. {
  472. CARLA_SAFE_ASSERT(! needsReset);
  473. CARLA_SAFE_ASSERT(transientTryCounter == 0);
  474. {
  475. // mutex MUST have been locked before
  476. const bool lockMaster(masterMutex.tryLock());
  477. const bool lockSingle(singleMutex.tryLock());
  478. CARLA_SAFE_ASSERT(! lockMaster);
  479. CARLA_SAFE_ASSERT(! lockSingle);
  480. }
  481. if (client != nullptr)
  482. {
  483. if (client->isActive())
  484. {
  485. // must not happen
  486. carla_safe_assert("client->isActive()", __FILE__, __LINE__);
  487. client->deactivate();
  488. }
  489. clearBuffers();
  490. delete client;
  491. client = nullptr;
  492. }
  493. if (name != nullptr)
  494. {
  495. delete[] name;
  496. name = nullptr;
  497. }
  498. if (filename != nullptr)
  499. {
  500. delete[] filename;
  501. filename = nullptr;
  502. }
  503. if (iconName != nullptr)
  504. {
  505. delete[] iconName;
  506. iconName = nullptr;
  507. }
  508. for (LinkedList<CustomData>::Itenerator it = custom.begin(); it.valid(); it.next())
  509. {
  510. CustomData& customData(it.getValue(kCustomDataFallbackNC));
  511. //CARLA_SAFE_ASSERT_CONTINUE(customData.isValid());
  512. if (customData.type != nullptr)
  513. {
  514. delete[] customData.type;
  515. customData.type = nullptr;
  516. }
  517. else
  518. carla_safe_assert("customData.type != nullptr", __FILE__, __LINE__);
  519. if (customData.key != nullptr)
  520. {
  521. delete[] customData.key;
  522. customData.key = nullptr;
  523. }
  524. else
  525. carla_safe_assert("customData.key != nullptr", __FILE__, __LINE__);
  526. if (customData.value != nullptr)
  527. {
  528. delete[] customData.value;
  529. customData.value = nullptr;
  530. }
  531. else
  532. carla_safe_assert("customData.value != nullptr", __FILE__, __LINE__);
  533. }
  534. prog.clear();
  535. midiprog.clear();
  536. custom.clear();
  537. // MUST have been locked before
  538. masterMutex.unlock();
  539. singleMutex.unlock();
  540. if (lib != nullptr)
  541. libClose();
  542. CARLA_SAFE_ASSERT(uiLib == nullptr);
  543. }
  544. // -----------------------------------------------------------------------
  545. // Buffer functions
  546. void CarlaPlugin::ProtectedData::clearBuffers() noexcept
  547. {
  548. audioIn.clear();
  549. audioOut.clear();
  550. cvIn.clear();
  551. cvOut.clear();
  552. param.clear();
  553. event.clear();
  554. latency.clearBuffers();
  555. }
  556. // -----------------------------------------------------------------------
  557. // Post-poned events
  558. void CarlaPlugin::ProtectedData::postponeRtEvent(const PluginPostRtEvent& rtEvent) noexcept
  559. {
  560. CARLA_SAFE_ASSERT_RETURN(rtEvent.type != kPluginPostRtEventNull,);
  561. postRtEvents.appendRT(rtEvent);
  562. }
  563. void CarlaPlugin::ProtectedData::postponeRtEvent(const PluginPostRtEventType type, const int32_t value1, const int32_t value2, const float value3) noexcept
  564. {
  565. CARLA_SAFE_ASSERT_RETURN(type != kPluginPostRtEventNull,);
  566. PluginPostRtEvent rtEvent = { type, value1, value2, value3 };
  567. postRtEvents.appendRT(rtEvent);
  568. }
  569. // -----------------------------------------------------------------------
  570. // Library functions
  571. static LibCounter sLibCounter;
  572. const char* CarlaPlugin::ProtectedData::libError(const char* const fname) noexcept
  573. {
  574. return lib_error(fname);
  575. }
  576. bool CarlaPlugin::ProtectedData::libOpen(const char* const fname) noexcept
  577. {
  578. lib = sLibCounter.open(fname);
  579. return (lib != nullptr);
  580. }
  581. bool CarlaPlugin::ProtectedData::libClose() noexcept
  582. {
  583. const bool ret = sLibCounter.close(lib);
  584. lib = nullptr;
  585. return ret;
  586. }
  587. bool CarlaPlugin::ProtectedData::uiLibOpen(const char* const fname, const bool canDelete) noexcept
  588. {
  589. uiLib = sLibCounter.open(fname, canDelete);
  590. return (uiLib != nullptr);
  591. }
  592. bool CarlaPlugin::ProtectedData::uiLibClose() noexcept
  593. {
  594. const bool ret = sLibCounter.close(uiLib);
  595. uiLib = nullptr;
  596. return ret;
  597. }
  598. // -----------------------------------------------------------------------
  599. #ifndef BUILD_BRIDGE
  600. void CarlaPlugin::ProtectedData::tryTransient() noexcept
  601. {
  602. if (engine->getOptions().frontendWinId != 0)
  603. transientTryCounter = 1;
  604. }
  605. #endif
  606. void CarlaPlugin::ProtectedData::updateParameterValues(CarlaPlugin* const plugin, const bool sendOsc, const bool sendCallback, const bool useDefault) noexcept
  607. {
  608. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback || useDefault,);
  609. for (uint32_t i=0; i < param.count; ++i)
  610. {
  611. const float value(param.ranges[i].getFixedValue(plugin->getParameterValue(i)));
  612. if (useDefault)
  613. param.ranges[i].def = value;
  614. #if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
  615. if (sendOsc)
  616. {
  617. if (useDefault)
  618. engine->oscSend_control_set_default_value(id, i, value);
  619. engine->oscSend_control_set_parameter_value(id, static_cast<int32_t>(i), value);
  620. }
  621. #endif
  622. if (sendCallback)
  623. {
  624. if (useDefault)
  625. engine->callback(ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED, id, static_cast<int>(i), 0, value, nullptr);
  626. engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, id, static_cast<int>(i), 0, value, nullptr);
  627. }
  628. }
  629. // may be unused
  630. return; (void)sendOsc;
  631. }
  632. // -----------------------------------------------------------------------
  633. CARLA_BACKEND_END_NAMESPACE