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.

821 lines
20KB

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