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.

786 lines
19KB

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