Lv2Proc.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. * Lv2Proc.h - Lv2 processor class
  3. *
  4. * Copyright (c) 2019-2020 Johannes Lorenz <jlsf2013$users.sourceforge.net, $=@>
  5. *
  6. * This file is part of LMMS - https://lmms.io
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2 of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public
  19. * License along with this program (see COPYING); if not, write to the
  20. * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  21. * Boston, MA 02110-1301 USA.
  22. *
  23. */
  24. #ifndef LV2PROC_H
  25. #define LV2PROC_H
  26. #include "lmmsconfig.h"
  27. #ifdef LMMS_HAVE_LV2
  28. #include <lilv/lilv.h>
  29. #include <memory>
  30. #include <QObject>
  31. #include "Lv2Basics.h"
  32. #include "Lv2Features.h"
  33. #include "Lv2Options.h"
  34. #include "LinkedModelGroups.h"
  35. #include "MidiEvent.h"
  36. #include "Plugin.h"
  37. #include "PluginIssue.h"
  38. #include "../src/3rdparty/ringbuffer/include/ringbuffer/ringbuffer.h"
  39. #include "TimePos.h"
  40. // forward declare port structs/enums
  41. namespace Lv2Ports
  42. {
  43. struct Audio;
  44. struct PortBase;
  45. struct AtomSeq;
  46. enum class Type;
  47. enum class Flow;
  48. enum class Vis;
  49. }
  50. //! Class representing one Lv2 processor, i.e. one Lv2 handle
  51. //! For Mono effects, 1 Lv2ControlBase references 2 Lv2Proc
  52. class Lv2Proc : public LinkedModelGroup
  53. {
  54. public:
  55. static Plugin::PluginTypes check(const LilvPlugin* plugin,
  56. std::vector<PluginIssue> &issues);
  57. /*
  58. ctor/dtor
  59. */
  60. Lv2Proc(const LilvPlugin* plugin, Model *parent);
  61. ~Lv2Proc() override;
  62. //! Must be checked after ctor or reload
  63. bool isValid() const { return m_valid; }
  64. /*
  65. port access
  66. */
  67. struct StereoPortRef
  68. {
  69. //! mono port or left port in case of stereo
  70. Lv2Ports::Audio* m_left = nullptr;
  71. //! unused, or right port in case of stereo
  72. Lv2Ports::Audio* m_right = nullptr;
  73. };
  74. StereoPortRef& inPorts() { return m_inPorts; }
  75. const StereoPortRef& inPorts() const { return m_inPorts; }
  76. StereoPortRef& outPorts() { return m_outPorts; }
  77. const StereoPortRef& outPorts() const { return m_outPorts; }
  78. template<class Functor>
  79. void foreach_port(const Functor& ftor)
  80. {
  81. for (std::unique_ptr<Lv2Ports::PortBase>& port : m_ports)
  82. {
  83. ftor(port.get());
  84. }
  85. }
  86. template<class Functor>
  87. void foreach_port(const Functor& ftor) const
  88. {
  89. for (const std::unique_ptr<Lv2Ports::PortBase>& port : m_ports)
  90. {
  91. ftor(port.get());
  92. }
  93. }
  94. //! Debug function to print ports to stdout
  95. void dumpPorts();
  96. /*
  97. utils for the run thread
  98. */
  99. //! Copy values from the LMMS core (connected models, MIDI events, ...) into
  100. //! the respective ports
  101. void copyModelsFromCore();
  102. //! Bring values from all ports to the LMMS core
  103. void copyModelsToCore();
  104. /**
  105. * Copy buffer passed by the core into our ports
  106. * @param buf buffer of sample frames, each sample frame is something like
  107. * a `float[<number-of-procs> * <channels per proc>]` array.
  108. * @param firstChan The offset for @p buf where we have to read our
  109. * first channel.
  110. * This marks the first sample in each sample frame where we read from.
  111. * If we are the 2nd of 2 mono procs, this can be greater than 0.
  112. * @param num Number of channels we must read from @param buf (starting at
  113. * @p offset)
  114. */
  115. void copyBuffersFromCore(const sampleFrame *buf,
  116. unsigned firstChan, unsigned num, fpp_t frames);
  117. /**
  118. * Copy our ports into buffers passed by the core
  119. * @param buf buffer of sample frames, each sample frame is something like
  120. * a `float[<number-of-procs> * <channels per proc>]` array.
  121. * @param firstChan The offset for @p buf where we have to write our
  122. * first channel.
  123. * This marks the first sample in each sample frame where we write to.
  124. * If we are the 2nd of 2 mono procs, this can be greater than 0.
  125. * @param num Number of channels we must write to @param buf (starting at
  126. * @p offset)
  127. */
  128. void copyBuffersToCore(sampleFrame *buf, unsigned firstChan, unsigned num,
  129. fpp_t frames) const;
  130. //! Run the Lv2 plugin instance for @param frames frames
  131. void run(fpp_t frames);
  132. void handleMidiInputEvent(const class MidiEvent &event,
  133. const TimePos &time, f_cnt_t offset);
  134. /*
  135. misc
  136. */
  137. class AutomatableModel *modelAtPort(const QString &uri); // unused currently
  138. std::size_t controlCount() const { return LinkedModelGroup::modelNum(); }
  139. bool hasNoteInput() const;
  140. protected:
  141. /*
  142. load and save
  143. */
  144. //! Create ports and instance, connect ports, activate plugin
  145. void initPlugin();
  146. //! Deactivate instance
  147. void shutdownPlugin();
  148. private:
  149. bool m_valid = true;
  150. const LilvPlugin* m_plugin;
  151. LilvInstance* m_instance;
  152. Lv2Features m_features;
  153. Lv2Options m_options;
  154. // full list of ports
  155. std::vector<std::unique_ptr<Lv2Ports::PortBase>> m_ports;
  156. // quick reference to specific, unique ports
  157. StereoPortRef m_inPorts, m_outPorts;
  158. Lv2Ports::AtomSeq *m_midiIn = nullptr, *m_midiOut = nullptr;
  159. // MIDI
  160. // many things here may be moved into the `Instrument` class
  161. constexpr const static std::size_t m_maxMidiInputEvents = 1024;
  162. //! spinlock for the MIDI ringbuffer (for MIDI events going to the plugin)
  163. std::atomic_flag m_ringLock = ATOMIC_FLAG_INIT;
  164. //! MIDI ringbuffer (for MIDI events going to the plugin)
  165. ringbuffer_t<struct MidiInputEvent> m_midiInputBuf;
  166. //! MIDI ringbuffer reader
  167. ringbuffer_reader_t<struct MidiInputEvent> m_midiInputReader;
  168. // other
  169. static int32_t defaultEvbufSize() { return 1 << 15; /* ardour uses this*/ }
  170. //! models for the controls, sorted by port symbols
  171. std::map<std::string, AutomatableModel *> m_connectedModels;
  172. void initMOptions(); //!< initialize m_options
  173. void initPluginSpecificFeatures();
  174. //! load a file in the plugin, but don't do anything in LMMS
  175. void loadFileInternal(const QString &file);
  176. //! allocate m_ports, fill all with metadata, and assign meaning of ports
  177. void createPorts();
  178. //! fill m_ports[portNum] with metadata
  179. void createPort(std::size_t portNum);
  180. //! connect m_ports[portNum] with Lv2
  181. void connectPort(std::size_t num);
  182. void dumpPort(std::size_t num);
  183. static bool portIsSideChain(const LilvPlugin* plugin, const LilvPort *port);
  184. static bool portIsOptional(const LilvPlugin* plugin, const LilvPort *port);
  185. static AutoLilvNode uri(const char* uriStr);
  186. };
  187. #endif // LMMS_HAVE_LV2
  188. #endif // LV2PROC_H