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.

774 lines
18KB

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