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.

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