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