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.

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