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.

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