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.

743 lines
17KB

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