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.

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