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.

817 lines
19KB

  1. /*
  2. * Carla Plugin
  3. * Copyright (C) 2011-2013 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 GPL.txt file
  16. */
  17. #ifndef __CARLA_PLUGIN_INTERNAL_HPP__
  18. #define __CARLA_PLUGIN_INTERNAL_HPP__
  19. #include "CarlaPlugin.hpp"
  20. #include "CarlaPluginThread.hpp"
  21. #include "CarlaEngine.hpp"
  22. #include "CarlaBackendUtils.hpp"
  23. #include "CarlaOscUtils.hpp"
  24. #include "CarlaMutex.hpp"
  25. #include "CarlaMIDI.h"
  26. #include "RtList.hpp"
  27. #define CARLA_PROCESS_CONTINUE_CHECK if (! fEnabled) { kData->engine->callback(CALLBACK_DEBUG, fId, 0, 0, 0.0f, "Processing while plugin is disabled!!"); return; }
  28. CARLA_BACKEND_START_NAMESPACE
  29. // -----------------------------------------------------------------------
  30. const unsigned short MAX_MIDI_EVENTS = 512;
  31. const unsigned int PLUGIN_HINT_HAS_MIDI_IN = 0x1;
  32. const unsigned int PLUGIN_HINT_HAS_MIDI_OUT = 0x2;
  33. const unsigned int PLUGIN_HINT_CAN_RUN_RACK = 0x4;
  34. // -----------------------------------------------------------------------
  35. struct PluginAudioPort {
  36. uint32_t rindex;
  37. CarlaEngineAudioPort* port;
  38. PluginAudioPort()
  39. : rindex(0),
  40. port(nullptr) {}
  41. ~PluginAudioPort()
  42. {
  43. CARLA_ASSERT(port == nullptr);
  44. }
  45. CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginAudioPort)
  46. };
  47. struct PluginAudioData {
  48. uint32_t count;
  49. PluginAudioPort* ports;
  50. PluginAudioData()
  51. : count(0),
  52. ports(nullptr) {}
  53. ~PluginAudioData()
  54. {
  55. CARLA_ASSERT_INT(count == 0, count);
  56. CARLA_ASSERT(ports == nullptr);
  57. }
  58. void createNew(const uint32_t newCount)
  59. {
  60. CARLA_ASSERT_INT(count == 0, count);
  61. CARLA_ASSERT(ports == nullptr);
  62. CARLA_ASSERT_INT(newCount > 0, newCount);
  63. if (ports != nullptr || newCount == 0)
  64. return;
  65. ports = new PluginAudioPort[newCount];
  66. count = newCount;
  67. }
  68. void clear()
  69. {
  70. if (ports != nullptr)
  71. {
  72. for (uint32_t i=0; i < count; ++i)
  73. {
  74. if (ports[i].port != nullptr)
  75. {
  76. delete ports[i].port;
  77. ports[i].port = nullptr;
  78. }
  79. }
  80. delete[] ports;
  81. ports = nullptr;
  82. }
  83. count = 0;
  84. }
  85. void initBuffers(CarlaEngine* const engine)
  86. {
  87. for (uint32_t i=0; i < count; ++i)
  88. {
  89. if (ports[i].port != nullptr)
  90. ports[i].port->initBuffer(engine);
  91. }
  92. }
  93. CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginAudioData)
  94. };
  95. // -----------------------------------------------------------------------
  96. struct PluginCVPort {
  97. uint32_t rindex;
  98. uint32_t param;
  99. CarlaEngineCVPort* port;
  100. PluginCVPort()
  101. : rindex(0),
  102. param(0),
  103. port(nullptr) {}
  104. ~PluginCVPort()
  105. {
  106. CARLA_ASSERT(port == nullptr);
  107. }
  108. CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginCVPort)
  109. };
  110. struct PluginCVData {
  111. uint32_t count;
  112. PluginCVPort* ports;
  113. PluginCVData()
  114. : count(0),
  115. ports(nullptr) {}
  116. ~PluginCVData()
  117. {
  118. CARLA_ASSERT_INT(count == 0, count);
  119. CARLA_ASSERT(ports == nullptr);
  120. }
  121. void createNew(const uint32_t newCount)
  122. {
  123. CARLA_ASSERT_INT(count == 0, count);
  124. CARLA_ASSERT(ports == nullptr);
  125. CARLA_ASSERT_INT(newCount > 0, newCount);
  126. if (ports != nullptr || newCount == 0)
  127. return;
  128. ports = new PluginCVPort[newCount];
  129. count = newCount;
  130. }
  131. void clear()
  132. {
  133. if (ports != nullptr)
  134. {
  135. for (uint32_t i=0; i < count; ++i)
  136. {
  137. if (ports[i].port != nullptr)
  138. {
  139. delete ports[i].port;
  140. ports[i].port = nullptr;
  141. }
  142. }
  143. delete[] ports;
  144. ports = nullptr;
  145. }
  146. count = 0;
  147. }
  148. void initBuffers(CarlaEngine* const engine)
  149. {
  150. for (uint32_t i=0; i < count; ++i)
  151. {
  152. if (ports[i].port != nullptr)
  153. ports[i].port->initBuffer(engine);
  154. }
  155. }
  156. CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginCVData)
  157. };
  158. // -----------------------------------------------------------------------
  159. struct PluginEventData {
  160. CarlaEngineEventPort* portIn;
  161. CarlaEngineEventPort* portOut;
  162. PluginEventData()
  163. : portIn(nullptr),
  164. portOut(nullptr) {}
  165. ~PluginEventData()
  166. {
  167. CARLA_ASSERT(portIn == nullptr);
  168. CARLA_ASSERT(portOut == nullptr);
  169. }
  170. void clear()
  171. {
  172. if (portIn != nullptr)
  173. {
  174. delete portIn;
  175. portIn = nullptr;
  176. }
  177. if (portOut != nullptr)
  178. {
  179. delete portOut;
  180. portOut = nullptr;
  181. }
  182. }
  183. void initBuffers(CarlaEngine* const engine)
  184. {
  185. if (portIn != nullptr)
  186. portIn->initBuffer(engine);
  187. if (portOut != nullptr)
  188. portOut->initBuffer(engine);
  189. }
  190. CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginEventData)
  191. };
  192. // -----------------------------------------------------------------------
  193. struct PluginParameterData {
  194. uint32_t count;
  195. ParameterData* data;
  196. ParameterRanges* ranges;
  197. PluginParameterData()
  198. : count(0),
  199. data(nullptr),
  200. ranges(nullptr) {}
  201. ~PluginParameterData()
  202. {
  203. CARLA_ASSERT_INT(count == 0, count);
  204. CARLA_ASSERT(data == nullptr);
  205. CARLA_ASSERT(ranges == nullptr);
  206. }
  207. void createNew(const uint32_t newCount)
  208. {
  209. CARLA_ASSERT_INT(count == 0, count);
  210. CARLA_ASSERT(data == nullptr);
  211. CARLA_ASSERT(ranges == nullptr);
  212. CARLA_ASSERT_INT(newCount > 0, newCount);
  213. if (data != nullptr || ranges != nullptr || newCount == 0)
  214. return;
  215. data = new ParameterData[newCount];
  216. ranges = new ParameterRanges[newCount];
  217. count = newCount;
  218. }
  219. void clear()
  220. {
  221. if (data != nullptr)
  222. {
  223. delete[] data;
  224. data = nullptr;
  225. }
  226. if (ranges != nullptr)
  227. {
  228. delete[] ranges;
  229. ranges = nullptr;
  230. }
  231. count = 0;
  232. }
  233. float fixValue(const uint32_t parameterId, const float& value)
  234. {
  235. CARLA_ASSERT_INT2(parameterId < count, parameterId, count);
  236. return ranges[parameterId].fixValue(value);
  237. }
  238. CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginParameterData)
  239. };
  240. // -----------------------------------------------------------------------
  241. typedef const char* ProgramName;
  242. struct PluginProgramData {
  243. uint32_t count;
  244. int32_t current;
  245. ProgramName* names;
  246. PluginProgramData()
  247. : count(0),
  248. current(-1),
  249. names(nullptr) {}
  250. ~PluginProgramData()
  251. {
  252. CARLA_ASSERT_INT(count == 0, count);
  253. CARLA_ASSERT_INT(current == -1, current);
  254. CARLA_ASSERT(names == nullptr);
  255. }
  256. void createNew(const uint32_t newCount)
  257. {
  258. CARLA_ASSERT_INT(count == 0, count);
  259. CARLA_ASSERT_INT(current == -1, current);
  260. CARLA_ASSERT(names == nullptr);
  261. CARLA_ASSERT_INT(newCount > 0, newCount);
  262. if (names != nullptr || newCount == 0)
  263. return;
  264. names = new ProgramName[newCount];
  265. count = newCount;
  266. for (uint32_t i=0; i < newCount; ++i)
  267. names[i] = nullptr;
  268. }
  269. void clear()
  270. {
  271. if (names != nullptr)
  272. {
  273. for (uint32_t i=0; i < count; ++i)
  274. {
  275. if (names[i] != nullptr)
  276. {
  277. delete[] names[i];
  278. names[i] = nullptr;
  279. }
  280. }
  281. delete[] names;
  282. names = nullptr;
  283. }
  284. count = 0;
  285. current = -1;
  286. }
  287. CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginProgramData)
  288. };
  289. // -----------------------------------------------------------------------
  290. struct PluginMidiProgramData {
  291. uint32_t count;
  292. int32_t current;
  293. MidiProgramData* data;
  294. PluginMidiProgramData()
  295. : count(0),
  296. current(-1),
  297. data(nullptr) {}
  298. ~PluginMidiProgramData()
  299. {
  300. CARLA_ASSERT_INT(count == 0, count);
  301. CARLA_ASSERT_INT(current == -1, current);
  302. CARLA_ASSERT(data == nullptr);
  303. }
  304. void createNew(const uint32_t newCount)
  305. {
  306. CARLA_ASSERT_INT(count == 0, count);
  307. CARLA_ASSERT_INT(current == -1, current);
  308. CARLA_ASSERT(data == nullptr);
  309. CARLA_ASSERT_INT(newCount > 0, newCount);
  310. if (data != nullptr || newCount == 0)
  311. return;
  312. data = new MidiProgramData[newCount];
  313. count = newCount;
  314. }
  315. void clear()
  316. {
  317. if (data != nullptr)
  318. {
  319. for (uint32_t i=0; i < count; ++i)
  320. {
  321. if (data[i].name != nullptr)
  322. {
  323. delete[] data[i].name;
  324. data[i].name = nullptr;
  325. }
  326. }
  327. delete[] data;
  328. data = nullptr;
  329. }
  330. count = 0;
  331. current = -1;
  332. }
  333. const MidiProgramData& getCurrent() const
  334. {
  335. CARLA_ASSERT_INT2(current >= 0 && current < static_cast<int32_t>(count), current, count);
  336. return data[current];
  337. }
  338. CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginMidiProgramData)
  339. };
  340. // -----------------------------------------------------------------------
  341. struct PluginPostRtEvent {
  342. PluginPostRtEventType type;
  343. int32_t value1;
  344. int32_t value2;
  345. float value3;
  346. PluginPostRtEvent()
  347. : type(kPluginPostRtEventNull),
  348. value1(-1),
  349. value2(-1),
  350. value3(0.0f) {}
  351. #ifndef DEBUG
  352. CARLA_DECLARE_NON_COPY_STRUCT(PluginPostRtEvent)
  353. #else
  354. CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PluginPostRtEvent)
  355. #endif
  356. };
  357. // -----------------------------------------------------------------------
  358. struct ExternalMidiNote {
  359. int8_t channel; // invalid == -1
  360. uint8_t note;
  361. uint8_t velo; // note-off if 0
  362. ExternalMidiNote()
  363. : channel(-1),
  364. note(0),
  365. velo(0) {}
  366. #ifndef DEBUG
  367. CARLA_DECLARE_NON_COPY_STRUCT(ExternalMidiNote)
  368. #else
  369. CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(ExternalMidiNote)
  370. #endif
  371. };
  372. // -----------------------------------------------------------------------
  373. class CarlaPluginGui;
  374. struct CarlaPluginProtectedData {
  375. CarlaEngine* const engine;
  376. CarlaEngineClient* client;
  377. CarlaPluginGui* gui;
  378. QByteArray guiGeometry;
  379. bool active;
  380. bool needsReset;
  381. void* lib;
  382. void* uiLib;
  383. // misc
  384. int8_t ctrlChannel;
  385. unsigned int extraHints;
  386. CarlaString idStr;
  387. // latency
  388. uint32_t latency;
  389. float** latencyBuffers;
  390. // data
  391. PluginAudioData audioIn;
  392. PluginAudioData audioOut;
  393. PluginEventData event;
  394. PluginParameterData param;
  395. PluginProgramData prog;
  396. PluginMidiProgramData midiprog;
  397. NonRtList<CustomData> custom;
  398. CarlaMutex masterMutex; // global master lock
  399. CarlaMutex singleMutex; // small lock used only in processSingle()
  400. struct ExternalNotes {
  401. CarlaMutex mutex;
  402. RtList<ExternalMidiNote>::Pool dataPool;
  403. RtList<ExternalMidiNote> data;
  404. ExternalNotes()
  405. : dataPool(32, 152),
  406. data(dataPool) {}
  407. ~ExternalNotes()
  408. {
  409. mutex.lock();
  410. data.clear();
  411. mutex.unlock();
  412. }
  413. void append(const ExternalMidiNote& note)
  414. {
  415. mutex.lock();
  416. data.append_sleepy(note);
  417. mutex.unlock();
  418. }
  419. CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(ExternalNotes)
  420. } extNotes;
  421. struct PostRtEvents {
  422. CarlaMutex mutex;
  423. RtList<PluginPostRtEvent>::Pool dataPool;
  424. RtList<PluginPostRtEvent> data;
  425. RtList<PluginPostRtEvent> dataPendingRT;
  426. PostRtEvents()
  427. : dataPool(128, 128),
  428. data(dataPool),
  429. dataPendingRT(dataPool) {}
  430. ~PostRtEvents()
  431. {
  432. clear();
  433. }
  434. void appendRT(const PluginPostRtEvent& event)
  435. {
  436. dataPendingRT.append(event);
  437. }
  438. void trySplice()
  439. {
  440. if (mutex.tryLock())
  441. {
  442. dataPendingRT.spliceAppend(data);
  443. mutex.unlock();
  444. }
  445. }
  446. void clear()
  447. {
  448. mutex.lock();
  449. data.clear();
  450. dataPendingRT.clear();
  451. mutex.unlock();
  452. }
  453. CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PostRtEvents)
  454. } postRtEvents;
  455. #ifndef BUILD_BRIDGE
  456. struct PostProc {
  457. float dryWet;
  458. float volume;
  459. float balanceLeft;
  460. float balanceRight;
  461. float panning;
  462. PostProc()
  463. : dryWet(1.0f),
  464. volume(1.0f),
  465. balanceLeft(-1.0f),
  466. balanceRight(1.0f),
  467. panning(0.0f) {}
  468. CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(PostProc)
  469. } postProc;
  470. #endif
  471. struct OSC {
  472. CarlaOscData data;
  473. CarlaPluginThread thread;
  474. OSC(CarlaEngine* const engine, CarlaPlugin* const plugin)
  475. : thread(engine, plugin) {}
  476. #ifdef CARLA_PROPER_CPP11_SUPPORT
  477. OSC() = delete;
  478. OSC(OSC&) = delete;
  479. OSC(const OSC&) = delete;
  480. #endif
  481. CARLA_LEAK_DETECTOR(OSC)
  482. } osc;
  483. CarlaPluginProtectedData(CarlaEngine* const engine_, CarlaPlugin* const plugin)
  484. : engine(engine_),
  485. client(nullptr),
  486. gui(nullptr),
  487. active(false),
  488. needsReset(false),
  489. lib(nullptr),
  490. uiLib(nullptr),
  491. ctrlChannel(0),
  492. extraHints(0x0),
  493. latency(0),
  494. latencyBuffers(nullptr),
  495. osc(engine, plugin) {}
  496. #ifdef CARLA_PROPER_CPP11_SUPPORT
  497. CarlaPluginProtectedData() = delete;
  498. CarlaPluginProtectedData(CarlaPluginProtectedData&) = delete;
  499. CarlaPluginProtectedData(const CarlaPluginProtectedData&) = delete;
  500. #endif
  501. CARLA_LEAK_DETECTOR(CarlaPluginProtectedData)
  502. ~CarlaPluginProtectedData()
  503. {
  504. CARLA_ASSERT(gui == nullptr);
  505. CARLA_ASSERT(client == nullptr);
  506. CARLA_ASSERT(! active);
  507. CARLA_ASSERT(lib == nullptr);
  508. CARLA_ASSERT(uiLib == nullptr);
  509. CARLA_ASSERT(latency == 0);
  510. CARLA_ASSERT(latencyBuffers == nullptr);
  511. CARLA_SAFE_ASSERT(! needsReset);
  512. }
  513. // -------------------------------------------------------------------
  514. // Cleanup
  515. void cleanup()
  516. {
  517. {
  518. const bool lockMaster(masterMutex.tryLock());
  519. const bool lockSingle(singleMutex.tryLock());
  520. CARLA_ASSERT(! lockMaster);
  521. CARLA_ASSERT(! lockSingle);
  522. }
  523. if (client != nullptr)
  524. {
  525. CARLA_ASSERT(! client->isActive());
  526. if (client->isActive())
  527. client->deactivate();
  528. clearBuffers();
  529. delete client;
  530. client = nullptr;
  531. }
  532. for (NonRtList<CustomData>::Itenerator it = custom.begin(); it.valid(); it.next())
  533. {
  534. CustomData& cData(*it);
  535. CARLA_ASSERT(cData.type != nullptr);
  536. CARLA_ASSERT(cData.key != nullptr);
  537. CARLA_ASSERT(cData.value != nullptr);
  538. if (cData.type != nullptr)
  539. {
  540. delete[] cData.type;
  541. cData.type = nullptr;
  542. }
  543. if (cData.key != nullptr)
  544. {
  545. delete[] cData.key;
  546. cData.key = nullptr;
  547. }
  548. if (cData.value != nullptr)
  549. {
  550. delete[] cData.value;
  551. cData.value = nullptr;
  552. }
  553. }
  554. prog.clear();
  555. midiprog.clear();
  556. custom.clear();
  557. // MUST have been locked before
  558. masterMutex.unlock();
  559. singleMutex.unlock();
  560. if (lib != nullptr)
  561. libClose();
  562. }
  563. // -------------------------------------------------------------------
  564. // Buffer functions
  565. void clearBuffers()
  566. {
  567. if (latencyBuffers != nullptr)
  568. {
  569. for (uint32_t i=0; i < audioIn.count; ++i)
  570. {
  571. CARLA_ASSERT(latencyBuffers[i] != nullptr);
  572. if (latencyBuffers[i] != nullptr)
  573. {
  574. delete[] latencyBuffers[i];
  575. latencyBuffers[i] = nullptr;
  576. }
  577. }
  578. delete[] latencyBuffers;
  579. latencyBuffers = nullptr;
  580. latency = 0;
  581. }
  582. audioIn.clear();
  583. audioOut.clear();
  584. param.clear();
  585. event.clear();
  586. }
  587. void recreateLatencyBuffers()
  588. {
  589. if (latencyBuffers != nullptr)
  590. {
  591. for (uint32_t i=0; i < audioIn.count; ++i)
  592. {
  593. CARLA_ASSERT(latencyBuffers[i] != nullptr);
  594. if (latencyBuffers[i] != nullptr)
  595. {
  596. delete[] latencyBuffers[i];
  597. latencyBuffers[i] = nullptr;
  598. }
  599. }
  600. delete[] latencyBuffers;
  601. latencyBuffers = nullptr;
  602. }
  603. if (audioIn.count > 0 && latency > 0)
  604. {
  605. latencyBuffers = new float*[audioIn.count];
  606. for (uint32_t i=0; i < audioIn.count; ++i)
  607. {
  608. latencyBuffers[i] = new float[latency];
  609. carla_zeroFloat(latencyBuffers[i], latency);
  610. }
  611. }
  612. }
  613. // -------------------------------------------------------------------
  614. // Library functions, see CarlaPlugin.cpp
  615. bool libOpen(const char* const filename);
  616. bool uiLibOpen(const char* const filename);
  617. bool libClose();
  618. bool uiLibClose();
  619. void* libSymbol(const char* const symbol);
  620. void* uiLibSymbol(const char* const symbol);
  621. const char* libError(const char* const filename);
  622. // -------------------------------------------------------------------
  623. // Settings functions, see CarlaPlugin.cpp
  624. void saveSetting(const unsigned int option, const bool yesNo);
  625. unsigned int loadSettings(const unsigned int options, const unsigned int availOptions);
  626. // -------------------------------------------------------------------
  627. // Static helper functions
  628. static CarlaEngine* getEngine(CarlaPlugin* const plugin)
  629. {
  630. return plugin->kData->engine;
  631. }
  632. static CarlaEngineClient* getEngineClient(CarlaPlugin* const plugin)
  633. {
  634. return plugin->kData->client;
  635. }
  636. static CarlaEngineAudioPort* getAudioInPort(CarlaPlugin* const plugin, const uint32_t index)
  637. {
  638. return plugin->kData->audioIn.ports[index].port;
  639. }
  640. static CarlaEngineAudioPort* getAudioOutPort(CarlaPlugin* const plugin, const uint32_t index)
  641. {
  642. return plugin->kData->audioOut.ports[index].port;
  643. }
  644. static bool canRunInRack(CarlaPlugin* const plugin)
  645. {
  646. return (plugin->kData->extraHints & PLUGIN_HINT_CAN_RUN_RACK);
  647. }
  648. };
  649. // -----------------------------------------------------------------------
  650. CARLA_BACKEND_END_NAMESPACE
  651. #endif // __CARLA_PLUGIN_INTERNAL_HPP__