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.

840 lines
21KB

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