Loading...
Searching...
No Matches
score-plugin-lv2/LV2/EffectModel.hpp
1#pragma once
2#include <Process/Execution/ProcessComponent.hpp>
3#include <Process/GenericProcessFactory.hpp>
4#include <Process/Process.hpp>
5
6#include <Control/DefaultEffectItem.hpp>
7#include <Effect/EffectFactory.hpp>
8#include <LV2/Context.hpp>
9#include <Process/Preset.hpp>
10
11#include <ossia/dataflow/node_process.hpp>
12
13#include <QTimer>
14
15#include <lilv/lilvmm.hpp>
16
17#include <score_plugin_lv2_export.h>
18
19#include <atomic>
20#include <optional>
21
22#include <verdigris>
23
24namespace LV2
25{
26class Model;
27// Call after a rescan: LilvPlugin* values may dangle if lilv rebuilt its index
28SCORE_PLUGIN_LV2_EXPORT void clearPluginCache();
29
30// Resolve a plug-in URI, bundle path or (legacy) display name against the
31// loaded world, loading its bundle on demand. Main thread only.
32// (get_lv2_plugin_name is declared in LV2/Context.hpp.)
33SCORE_PLUGIN_LV2_TEST_EXPORT std::optional<Lilv::Plugin>
34find_lv2_plugin(Lilv::World& world, QString path);
35}
36PROCESS_METADATA(
37 , LV2::Model, "fd5243ba-70b5-4164-b44a-ecb0dcdc0494", "LV2", "LV2",
38 Process::ProcessCategory::Other, "Plugins", "LV2 plug-in", "ossia score", {}, {}, {},
39 QUrl("https://ossia.io/score-docs/processes/audio-plugins.html#common-formats-vst-vst3-lv2-jsfx"),
40 Process::ProcessFlags::ExternalEffect)
41DESCRIPTION_METADATA(, LV2::Model, "LV2")
42namespace LV2
43{
44class SCORE_PLUGIN_LV2_EXPORT Model : public Process::ProcessModel
45{
46 W_OBJECT(Model)
47 SCORE_SERIALIZE_FRIENDS
48public:
49 PROCESS_METADATA_IMPL(Model)
50 Model(
51 TimeVal t, const QString& name, const Id<Process::ProcessModel>&, QObject* parent);
52
53 ~Model() override;
54 template <typename Impl>
55 Model(Impl& vis, QObject* parent)
56 : ProcessModel{vis, parent}
57 {
58 vis.writeTo(*this);
59 }
60
61 QString effect() const noexcept override { return m_effectPath; }
62
63 void setEffect(const QString& s) { m_effectPath = s; }
64
65 QString prettyName() const noexcept override;
66
67 bool hasExternalUI() const noexcept;
68
69 void loadPreset(const Process::Preset& preset) override;
71 bool presetChangesPorts(const Process::Preset&) const noexcept override
72 {
73 return false;
74 }
75 Process::Preset savePreset() const noexcept override;
76 std::vector<Process::Preset> builtinPresets() const noexcept override;
77
78 const LilvPlugin* plugin{};
79 mutable LV2::EffectContext effectContext;
80 LV2::HostContext* hostContext{};
81
82 std::size_t m_controlInStart{};
83 std::size_t m_controlOutStart{};
84 mutable moodycamel::ReaderWriterQueue<Message> ui_events; // from ui to score
85 mutable moodycamel::ReaderWriterQueue<Message> plugin_events; // from plug-in
88 mutable std::atomic_bool uiListening{false};
89 mutable moodycamel::ReaderWriterQueue<Message>
90 to_process_events; // from score to process
91
92 ossia::hash_map<uint32_t, std::pair<Process::ControlInlet*, bool>> control_map;
94 mutable float portValueForState{};
95 ossia::hash_map<uint32_t, Process::ControlOutlet*> control_out_map;
97 ossia::hash_set<uint32_t> sample_rate_ports;
98
100 float toPlugin(uint32_t port_index, float v) const noexcept;
101 float fromPlugin(uint32_t port_index, float v) const noexcept;
102
103private:
104 void reload();
105 QString m_effectPath;
106 void readPlugin();
107
108 ossia::float_vector fInControls, fOutControls;
109};
110
111class LV2EffectComponent final
112 : public Execution::ProcessComponent_T<LV2::Model, ossia::node_process>
113{
114 W_OBJECT(LV2EffectComponent)
115 COMPONENT_METADATA("57f50003-a179-424a-80b1-b9394d73a84a")
116
117public:
118 static constexpr bool is_unique = true;
119
120 LV2EffectComponent(LV2::Model& proc, const Execution::Context& ctx, QObject* parent);
121
122 void lazy_init() override;
123
124 void
125 writeAtomToUi(uint32_t port_index, uint32_t type, uint32_t size, const void* body);
126 void writeAtomToUi(uint32_t port_index, const LV2_Atom& atom);
127
128private:
129 // per_channel voice-pool grower (main thread). Audio thread pushes high-water mark.
130 QTimer* m_grow_timer{};
131 int m_pool_sample_rate{};
132 std::size_t m_pool_pushed{};
133 std::size_t m_pool_max_requested{};
134
135 void growVoicePoolTick();
136};
137}
138
139namespace Process
140{
141template <>
142QString EffectProcessFactory_T<LV2::Model>::customConstructionData() const noexcept;
143}
144
145namespace LV2
146{
147using ProcessFactory = Process::EffectProcessFactory_T<Model>;
149}
Definition Process/Execution/ProcessComponent.hpp:131
Definition EffectFactory.hpp:14
The Process class.
Definition score-lib-process/Process/Process.hpp:82
The id_base_t class.
Definition Identifier.hpp:59
Components used for the execution of a score.
Definition PortTap.cpp:24
Base classes and tools to implement processes and layers.
Definition JSONVisitor.hpp:1115
STL namespace.
Definition Process/Execution/ProcessComponent.hpp:101
Definition Context.hpp:198
Definition Context.hpp:61
Definition Preset.hpp:32
Definition TimeValue.hpp:21