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.

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