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.

812 lines
20KB

  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. latencyBuffers(nullptr),
  394. name(nullptr),
  395. filename(nullptr),
  396. #ifndef BUILD_BRIDGE
  397. iconName(nullptr),
  398. identifier(nullptr),
  399. #endif
  400. osc(eng, plug) {}
  401. CarlaPlugin::ProtectedData::~ProtectedData() noexcept
  402. {
  403. CARLA_SAFE_ASSERT(! needsReset);
  404. CARLA_SAFE_ASSERT(transientTryCounter == 0);
  405. {
  406. // mutex MUST have been locked before
  407. const bool lockMaster(masterMutex.tryLock());
  408. const bool lockSingle(singleMutex.tryLock());
  409. CARLA_SAFE_ASSERT(! lockMaster);
  410. CARLA_SAFE_ASSERT(! lockSingle);
  411. }
  412. if (client != nullptr)
  413. {
  414. if (client->isActive())
  415. {
  416. // must not happen
  417. carla_safe_assert("client->isActive()", __FILE__, __LINE__);
  418. client->deactivate();
  419. }
  420. clearBuffers();
  421. delete client;
  422. client = nullptr;
  423. }
  424. if (name != nullptr)
  425. {
  426. delete[] name;
  427. name = nullptr;
  428. }
  429. if (filename != nullptr)
  430. {
  431. delete[] filename;
  432. filename = nullptr;
  433. }
  434. #ifndef BUILD_BRIDGE
  435. if (iconName != nullptr)
  436. {
  437. delete[] iconName;
  438. iconName = nullptr;
  439. }
  440. if (identifier != nullptr)
  441. {
  442. delete[] identifier;
  443. identifier = nullptr;
  444. }
  445. #endif
  446. for (LinkedList<CustomData>::Itenerator it = custom.begin(); it.valid(); it.next())
  447. {
  448. CustomData& cData(it.getValue());
  449. if (cData.type != nullptr)
  450. {
  451. delete[] cData.type;
  452. cData.type = nullptr;
  453. }
  454. else
  455. carla_safe_assert("cData.type != nullptr", __FILE__, __LINE__);
  456. if (cData.key != nullptr)
  457. {
  458. delete[] cData.key;
  459. cData.key = nullptr;
  460. }
  461. else
  462. carla_safe_assert("cData.key != nullptr", __FILE__, __LINE__);
  463. if (cData.value != nullptr)
  464. {
  465. delete[] cData.value;
  466. cData.value = nullptr;
  467. }
  468. else
  469. carla_safe_assert("cData.value != nullptr", __FILE__, __LINE__);
  470. }
  471. prog.clear();
  472. midiprog.clear();
  473. custom.clear();
  474. // MUST have been locked before
  475. masterMutex.unlock();
  476. singleMutex.unlock();
  477. if (lib != nullptr)
  478. libClose();
  479. CARLA_SAFE_ASSERT(uiLib == nullptr);
  480. }
  481. // -----------------------------------------------------------------------
  482. // Buffer functions
  483. void CarlaPlugin::ProtectedData::clearBuffers() noexcept
  484. {
  485. if (latencyBuffers != nullptr)
  486. {
  487. CARLA_SAFE_ASSERT(audioIn.count > 0);
  488. for (uint32_t i=0; i < audioIn.count; ++i)
  489. {
  490. CARLA_SAFE_ASSERT_CONTINUE(latencyBuffers[i] != nullptr);
  491. delete[] latencyBuffers[i];
  492. latencyBuffers[i] = nullptr;
  493. }
  494. delete[] latencyBuffers;
  495. latencyBuffers = nullptr;
  496. latency = 0;
  497. }
  498. else
  499. {
  500. if (latency != 0)
  501. {
  502. #ifndef BUILD_BRIDGE
  503. carla_safe_assert_int("latency != 0", __FILE__, __LINE__, static_cast<int>(latency));
  504. #endif
  505. latency = 0;
  506. }
  507. }
  508. audioIn.clear();
  509. audioOut.clear();
  510. param.clear();
  511. event.clear();
  512. }
  513. #ifndef BUILD_BRIDGE
  514. void CarlaPlugin::ProtectedData::recreateLatencyBuffers()
  515. {
  516. if (latencyBuffers != nullptr)
  517. {
  518. CARLA_SAFE_ASSERT(audioIn.count > 0);
  519. for (uint32_t i=0; i < audioIn.count; ++i)
  520. {
  521. CARLA_SAFE_ASSERT_CONTINUE(latencyBuffers[i] != nullptr);
  522. delete[] latencyBuffers[i];
  523. latencyBuffers[i] = nullptr;
  524. }
  525. delete[] latencyBuffers;
  526. latencyBuffers = nullptr;
  527. }
  528. if (audioIn.count > 0 && latency > 0)
  529. {
  530. latencyBuffers = new float*[audioIn.count];
  531. for (uint32_t i=0; i < audioIn.count; ++i)
  532. {
  533. latencyBuffers[i] = new float[latency];
  534. FLOAT_CLEAR(latencyBuffers[i], latency);
  535. }
  536. }
  537. }
  538. #endif
  539. // -----------------------------------------------------------------------
  540. // Post-poned events
  541. void CarlaPlugin::ProtectedData::postponeRtEvent(const PluginPostRtEvent& rtEvent) noexcept
  542. {
  543. CARLA_SAFE_ASSERT_RETURN(rtEvent.type != kPluginPostRtEventNull,);
  544. postRtEvents.appendRT(rtEvent);
  545. }
  546. void CarlaPlugin::ProtectedData::postponeRtEvent(const PluginPostRtEventType type, const int32_t value1, const int32_t value2, const float value3) noexcept
  547. {
  548. CARLA_SAFE_ASSERT_RETURN(type != kPluginPostRtEventNull,);
  549. PluginPostRtEvent rtEvent = { type, value1, value2, value3 };
  550. postRtEvents.appendRT(rtEvent);
  551. }
  552. // -----------------------------------------------------------------------
  553. // Library functions
  554. static LibCounter sLibCounter;
  555. const char* CarlaPlugin::ProtectedData::libError(const char* const fname) noexcept
  556. {
  557. return lib_error(fname);
  558. }
  559. bool CarlaPlugin::ProtectedData::libOpen(const char* const fname) noexcept
  560. {
  561. lib = sLibCounter.open(fname);
  562. return (lib != nullptr);
  563. }
  564. bool CarlaPlugin::ProtectedData::libClose() noexcept
  565. {
  566. const bool ret = sLibCounter.close(lib);
  567. lib = nullptr;
  568. return ret;
  569. }
  570. void* CarlaPlugin::ProtectedData::libSymbol(const char* const symbol) const noexcept
  571. {
  572. return lib_symbol(lib, symbol);
  573. }
  574. bool CarlaPlugin::ProtectedData::uiLibOpen(const char* const fname, const bool canDelete) noexcept
  575. {
  576. uiLib = sLibCounter.open(fname, canDelete);
  577. return (uiLib != nullptr);
  578. }
  579. bool CarlaPlugin::ProtectedData::uiLibClose() noexcept
  580. {
  581. const bool ret = sLibCounter.close(uiLib);
  582. uiLib = nullptr;
  583. return ret;
  584. }
  585. void* CarlaPlugin::ProtectedData::uiLibSymbol(const char* const symbol) const noexcept
  586. {
  587. return lib_symbol(uiLib, symbol);
  588. }
  589. // -----------------------------------------------------------------------
  590. // Settings functions
  591. void CarlaPlugin::ProtectedData::saveSetting(const uint option, const bool yesNo) const
  592. {
  593. CARLA_SAFE_ASSERT_RETURN(identifier != nullptr && identifier[0] != '\0',);
  594. QSettings settings("falkTX", "CarlaPluginSettings");
  595. settings.beginGroup(identifier);
  596. switch (option)
  597. {
  598. case PLUGIN_OPTION_FIXED_BUFFERS:
  599. settings.setValue("FixedBuffers", yesNo);
  600. break;
  601. case PLUGIN_OPTION_FORCE_STEREO:
  602. settings.setValue("ForceStereo", yesNo);
  603. break;
  604. case PLUGIN_OPTION_MAP_PROGRAM_CHANGES:
  605. settings.setValue("MapProgramChanges", yesNo);
  606. break;
  607. case PLUGIN_OPTION_USE_CHUNKS:
  608. settings.setValue("UseChunks", yesNo);
  609. break;
  610. case PLUGIN_OPTION_SEND_CONTROL_CHANGES:
  611. settings.setValue("SendControlChanges", yesNo);
  612. break;
  613. case PLUGIN_OPTION_SEND_CHANNEL_PRESSURE:
  614. settings.setValue("SendChannelPressure", yesNo);
  615. break;
  616. case PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH:
  617. settings.setValue("SendNoteAftertouch", yesNo);
  618. break;
  619. case PLUGIN_OPTION_SEND_PITCHBEND:
  620. settings.setValue("SendPitchbend", yesNo);
  621. break;
  622. case PLUGIN_OPTION_SEND_ALL_SOUND_OFF:
  623. settings.setValue("SendAllSoundOff", yesNo);
  624. break;
  625. default:
  626. break;
  627. }
  628. settings.endGroup();
  629. }
  630. uint CarlaPlugin::ProtectedData::loadSettings(const uint curOptions, const uint availOptions) const
  631. {
  632. CARLA_SAFE_ASSERT_RETURN(identifier != nullptr && identifier[0] != '\0', 0x0);
  633. QSettings settings("falkTX", "CarlaPluginSettings");
  634. settings.beginGroup(identifier);
  635. uint newOptions = 0x0;
  636. #define CHECK_AND_SET_OPTION(STR, BIT) \
  637. if ((availOptions & BIT) != 0 || BIT == PLUGIN_OPTION_FORCE_STEREO) \
  638. { \
  639. if (settings.contains(STR)) \
  640. { \
  641. if (settings.value(STR, bool((curOptions & BIT) != 0)).toBool()) \
  642. newOptions |= BIT; \
  643. } \
  644. else if (curOptions & BIT) \
  645. newOptions |= BIT; \
  646. }
  647. CHECK_AND_SET_OPTION("FixedBuffers", PLUGIN_OPTION_FIXED_BUFFERS);
  648. CHECK_AND_SET_OPTION("ForceStereo", PLUGIN_OPTION_FORCE_STEREO);
  649. CHECK_AND_SET_OPTION("MapProgramChanges", PLUGIN_OPTION_MAP_PROGRAM_CHANGES);
  650. CHECK_AND_SET_OPTION("UseChunks", PLUGIN_OPTION_USE_CHUNKS);
  651. CHECK_AND_SET_OPTION("SendControlChanges", PLUGIN_OPTION_SEND_CONTROL_CHANGES);
  652. CHECK_AND_SET_OPTION("SendChannelPressure", PLUGIN_OPTION_SEND_CHANNEL_PRESSURE);
  653. CHECK_AND_SET_OPTION("SendNoteAftertouch", PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH);
  654. CHECK_AND_SET_OPTION("SendPitchbend", PLUGIN_OPTION_SEND_PITCHBEND);
  655. CHECK_AND_SET_OPTION("SendAllSoundOff", PLUGIN_OPTION_SEND_ALL_SOUND_OFF);
  656. #undef CHECK_AND_SET_OPTION
  657. settings.endGroup();
  658. return newOptions;
  659. }
  660. // -----------------------------------------------------------------------
  661. void CarlaPlugin::ProtectedData::tryTransient() noexcept
  662. {
  663. if (engine->getOptions().frontendWinId != 0)
  664. transientTryCounter = 1;
  665. }
  666. // -----------------------------------------------------------------------
  667. CARLA_BACKEND_END_NAMESPACE