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.

747 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::PostRtEvents
  318. CarlaPlugin::ProtectedData::PostRtEvents::PostRtEvents() noexcept
  319. : mutex(),
  320. dataPool(128, 128),
  321. data(dataPool),
  322. dataPendingRT(dataPool) {}
  323. CarlaPlugin::ProtectedData::PostRtEvents::~PostRtEvents() noexcept
  324. {
  325. clear();
  326. }
  327. void CarlaPlugin::ProtectedData::PostRtEvents::appendRT(const PluginPostRtEvent& e) noexcept
  328. {
  329. dataPendingRT.append(e);
  330. }
  331. void CarlaPlugin::ProtectedData::PostRtEvents::trySplice() noexcept
  332. {
  333. if (mutex.tryLock())
  334. {
  335. if (dataPendingRT.count() > 0)
  336. dataPendingRT.moveTo(data, true);
  337. mutex.unlock();
  338. }
  339. }
  340. void CarlaPlugin::ProtectedData::PostRtEvents::clear() noexcept
  341. {
  342. mutex.lock();
  343. data.clear();
  344. dataPendingRT.clear();
  345. mutex.unlock();
  346. }
  347. #ifndef BUILD_BRIDGE
  348. // -----------------------------------------------------------------------
  349. // ProtectedData::PostProc
  350. CarlaPlugin::ProtectedData::PostProc::PostProc() noexcept
  351. : dryWet(1.0f),
  352. volume(1.0f),
  353. balanceLeft(-1.0f),
  354. balanceRight(1.0f),
  355. panning(0.0f) {}
  356. #endif
  357. // -----------------------------------------------------------------------
  358. CarlaPlugin::ProtectedData::ProtectedData(CarlaEngine* const eng, const uint idx) noexcept
  359. : engine(eng),
  360. client(nullptr),
  361. id(idx),
  362. hints(0x0),
  363. options(0x0),
  364. nodeId(0),
  365. active(false),
  366. enabled(false),
  367. needsReset(false),
  368. lib(nullptr),
  369. uiLib(nullptr),
  370. ctrlChannel(0),
  371. extraHints(0x0),
  372. transientTryCounter(0),
  373. latency(0),
  374. #ifndef BUILD_BRIDGE
  375. latencyBuffers(nullptr),
  376. #endif
  377. name(nullptr),
  378. filename(nullptr),
  379. iconName(nullptr),
  380. audioIn(),
  381. audioOut(),
  382. cvIn(),
  383. cvOut(),
  384. event(),
  385. param(),
  386. prog(),
  387. midiprog(),
  388. custom(),
  389. masterMutex(),
  390. singleMutex(),
  391. #ifndef BUILD_BRIDGE
  392. childProcess(),
  393. oscData(),
  394. #endif
  395. stateSave(),
  396. extNotes(),
  397. postRtEvents(),
  398. #ifndef BUILD_BRIDGE
  399. postProc(),
  400. #endif
  401. leakDetector_ProtectedData() {}
  402. CarlaPlugin::ProtectedData::~ProtectedData() noexcept
  403. {
  404. CARLA_SAFE_ASSERT(! needsReset);
  405. CARLA_SAFE_ASSERT(transientTryCounter == 0);
  406. {
  407. // mutex MUST have been locked before
  408. const bool lockMaster(masterMutex.tryLock());
  409. const bool lockSingle(singleMutex.tryLock());
  410. CARLA_SAFE_ASSERT(! lockMaster);
  411. CARLA_SAFE_ASSERT(! lockSingle);
  412. }
  413. if (client != nullptr)
  414. {
  415. if (client->isActive())
  416. {
  417. // must not happen
  418. carla_safe_assert("client->isActive()", __FILE__, __LINE__);
  419. client->deactivate();
  420. }
  421. clearBuffers();
  422. delete client;
  423. client = nullptr;
  424. }
  425. if (name != nullptr)
  426. {
  427. delete[] name;
  428. name = nullptr;
  429. }
  430. if (filename != nullptr)
  431. {
  432. delete[] filename;
  433. filename = nullptr;
  434. }
  435. if (iconName != nullptr)
  436. {
  437. delete[] iconName;
  438. iconName = nullptr;
  439. }
  440. for (LinkedList<CustomData>::Itenerator it = custom.begin(); it.valid(); it.next())
  441. {
  442. CustomData& customData(it.getValue(kCustomDataFallbackNC));
  443. //CARLA_SAFE_ASSERT_CONTINUE(customData.isValid());
  444. if (customData.type != nullptr)
  445. {
  446. delete[] customData.type;
  447. customData.type = nullptr;
  448. }
  449. else
  450. carla_safe_assert("customData.type != nullptr", __FILE__, __LINE__);
  451. if (customData.key != nullptr)
  452. {
  453. delete[] customData.key;
  454. customData.key = nullptr;
  455. }
  456. else
  457. carla_safe_assert("customData.key != nullptr", __FILE__, __LINE__);
  458. if (customData.value != nullptr)
  459. {
  460. delete[] customData.value;
  461. customData.value = nullptr;
  462. }
  463. else
  464. carla_safe_assert("customData.value != nullptr", __FILE__, __LINE__);
  465. }
  466. prog.clear();
  467. midiprog.clear();
  468. custom.clear();
  469. // MUST have been locked before
  470. masterMutex.unlock();
  471. singleMutex.unlock();
  472. if (lib != nullptr)
  473. libClose();
  474. CARLA_SAFE_ASSERT(uiLib == nullptr);
  475. }
  476. // -----------------------------------------------------------------------
  477. // Buffer functions
  478. void CarlaPlugin::ProtectedData::clearBuffers() noexcept
  479. {
  480. #ifndef BUILD_BRIDGE
  481. if (latencyBuffers != nullptr)
  482. {
  483. CARLA_SAFE_ASSERT(audioIn.count > 0);
  484. for (uint32_t i=0; i < audioIn.count; ++i)
  485. {
  486. CARLA_SAFE_ASSERT_CONTINUE(latencyBuffers[i] != nullptr);
  487. delete[] latencyBuffers[i];
  488. latencyBuffers[i] = nullptr;
  489. }
  490. delete[] latencyBuffers;
  491. latencyBuffers = nullptr;
  492. latency = 0;
  493. }
  494. else
  495. {
  496. if (latency != 0)
  497. {
  498. carla_safe_assert_int("latency != 0", __FILE__, __LINE__, static_cast<int>(latency));
  499. latency = 0;
  500. }
  501. }
  502. #else
  503. latency = 0;
  504. #endif
  505. audioIn.clear();
  506. audioOut.clear();
  507. cvIn.clear();
  508. cvOut.clear();
  509. param.clear();
  510. event.clear();
  511. }
  512. #ifndef BUILD_BRIDGE
  513. void CarlaPlugin::ProtectedData::recreateLatencyBuffers()
  514. {
  515. if (latencyBuffers != nullptr)
  516. {
  517. CARLA_SAFE_ASSERT(audioIn.count > 0);
  518. for (uint32_t i=0; i < audioIn.count; ++i)
  519. {
  520. CARLA_SAFE_ASSERT_CONTINUE(latencyBuffers[i] != nullptr);
  521. delete[] latencyBuffers[i];
  522. latencyBuffers[i] = nullptr;
  523. }
  524. delete[] latencyBuffers;
  525. latencyBuffers = nullptr;
  526. }
  527. if (audioIn.count > 0 && latency > 0)
  528. {
  529. latencyBuffers = new float*[audioIn.count];
  530. for (uint32_t i=0; i < audioIn.count; ++i)
  531. {
  532. latencyBuffers[i] = new float[latency];
  533. FloatVectorOperations::clear(latencyBuffers[i], static_cast<int>(latency));
  534. }
  535. }
  536. }
  537. #endif
  538. // -----------------------------------------------------------------------
  539. // Post-poned events
  540. void CarlaPlugin::ProtectedData::postponeRtEvent(const PluginPostRtEvent& rtEvent) noexcept
  541. {
  542. CARLA_SAFE_ASSERT_RETURN(rtEvent.type != kPluginPostRtEventNull,);
  543. postRtEvents.appendRT(rtEvent);
  544. }
  545. void CarlaPlugin::ProtectedData::postponeRtEvent(const PluginPostRtEventType type, const int32_t value1, const int32_t value2, const float value3) noexcept
  546. {
  547. CARLA_SAFE_ASSERT_RETURN(type != kPluginPostRtEventNull,);
  548. PluginPostRtEvent rtEvent = { type, value1, value2, value3 };
  549. postRtEvents.appendRT(rtEvent);
  550. }
  551. // -----------------------------------------------------------------------
  552. // Library functions
  553. static LibCounter sLibCounter;
  554. const char* CarlaPlugin::ProtectedData::libError(const char* const fname) noexcept
  555. {
  556. return lib_error(fname);
  557. }
  558. bool CarlaPlugin::ProtectedData::libOpen(const char* const fname) noexcept
  559. {
  560. lib = sLibCounter.open(fname);
  561. return (lib != nullptr);
  562. }
  563. bool CarlaPlugin::ProtectedData::libClose() noexcept
  564. {
  565. const bool ret = sLibCounter.close(lib);
  566. lib = nullptr;
  567. return ret;
  568. }
  569. bool CarlaPlugin::ProtectedData::uiLibOpen(const char* const fname, const bool canDelete) noexcept
  570. {
  571. uiLib = sLibCounter.open(fname, canDelete);
  572. return (uiLib != nullptr);
  573. }
  574. bool CarlaPlugin::ProtectedData::uiLibClose() noexcept
  575. {
  576. const bool ret = sLibCounter.close(uiLib);
  577. uiLib = nullptr;
  578. return ret;
  579. }
  580. // -----------------------------------------------------------------------
  581. void CarlaPlugin::ProtectedData::tryTransient() noexcept
  582. {
  583. if (engine->getOptions().frontendWinId != 0)
  584. transientTryCounter = 1;
  585. }
  586. void CarlaPlugin::ProtectedData::updateParameterValues(CarlaPlugin* const plugin, const bool sendOsc, const bool sendCallback, const bool useDefault) noexcept
  587. {
  588. CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback || useDefault,);
  589. for (uint32_t i=0; i < param.count; ++i)
  590. {
  591. const float value(param.ranges[i].getFixedValue(plugin->getParameterValue(i)));
  592. if (useDefault)
  593. param.ranges[i].def = value;
  594. #ifndef BUILD_BRIDGE
  595. if (sendOsc)
  596. {
  597. if (useDefault)
  598. engine->oscSend_control_set_default_value(id, i, value);
  599. engine->oscSend_control_set_parameter_value(id, static_cast<int32_t>(i), value);
  600. }
  601. #endif
  602. if (sendCallback)
  603. {
  604. if (useDefault)
  605. engine->callback(ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED, id, static_cast<int>(i), 0, value, nullptr);
  606. engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, id, static_cast<int>(i), 0, value, nullptr);
  607. }
  608. }
  609. #ifdef BUILD_BRIDGE
  610. // unused
  611. return; (void)sendOsc;
  612. #endif
  613. }
  614. // -----------------------------------------------------------------------
  615. CARLA_BACKEND_END_NAMESPACE