score-plugin-vst/Vst/EffectModel.hpp
1 #pragma once
2 #include <Process/Dataflow/PortFactory.hpp>
3 #include <Process/GenericProcessFactory.hpp>
4 #include <Process/Process.hpp>
5 
6 #include <Control/DefaultEffectItem.hpp>
7 #include <Effect/EffectFactory.hpp>
8 #include <Vst/Loader.hpp>
9 
10 #include <score/tools/std/Invoke.hpp>
11 
12 #include <ossia/detail/hash_map.hpp>
13 
14 #include <verdigris>
15 namespace vst
16 {
17 class Model;
18 class ControlInlet;
19 }
20 PROCESS_METADATA(
21  , vst::Model, "BE8E6BD3-75F2-4102-8895-8A4EB4EA545A", "VST", "VST",
22  Process::ProcessCategory::Other, "Plugins", "VST plug-in",
23  "VST is a trademark of Steinberg Media Technologies GmbH", {}, {}, {},
24  Process::ProcessFlags::ExternalEffect)
25 UUID_METADATA(, Process::Port, vst::ControlInlet, "e523bc44-8599-4a04-94c1-04ce0d1a692a")
26 DESCRIPTION_METADATA(, vst::Model, "")
27 namespace vst
28 {
29 #define VST_FIRST_CONTROL_INDEX(synth) ((synth) ? 2 : 1)
30 struct AEffectWrapper
31 {
32  AEffect* fx{};
33  VstTimeInfo info;
34  bool ui_opened{};
35 
36  AEffectWrapper(AEffect* f) noexcept
37  : fx{f}
38  {
39  }
40 
41  auto getParameter(int32_t index) const noexcept { return fx->getParameter(fx, index); }
42  auto setParameter(int32_t index, float p) const noexcept
43  {
44  return fx->setParameter(fx, index, p);
45  }
46 
47  auto dispatch(
48  int32_t opcode, int32_t index = 0, intptr_t value = 0, void* ptr = nullptr,
49  float opt = 0.0f) const noexcept
50  {
51  return fx->dispatcher(fx, opcode, index, value, ptr, opt);
52  }
53 
54  ~AEffectWrapper();
55 };
56 
57 class CreateControl;
58 class ControlInlet;
59 class Model final : public Process::ProcessModel
60 {
61  W_OBJECT(Model)
62  SCORE_SERIALIZE_FRIENDS
63  friend class vst::CreateControl;
64 
65 public:
66  MODEL_METADATA_IMPL(Model)
67  Model(
68  TimeVal t, const QString& name, const Id<Process::ProcessModel>&, QObject* parent);
69 
70  ~Model() override;
71  template <typename Impl>
72  Model(Impl& vis, QObject* parent)
73  : ProcessModel{vis, parent}
74  , m_registration{*this}
75  {
76  init();
77  vis.writeTo(*this);
78  }
79 
80  QString prettyShortName() const noexcept override
81  {
83  }
84  QString category() const noexcept override
85  {
87  }
88  QStringList tags() const noexcept override { return Metadata<Tags_k, Model>::get(); }
89  Process::ProcessFlags flags() const noexcept override;
90  void setCreatingControls(bool ok) override;
91 
92  ControlInlet* getControl(const Id<Process::Port>& p) const;
93  QString effect() const noexcept override;
94  QString prettyName() const noexcept override;
95  bool hasExternalUI() const noexcept;
96 
97  std::shared_ptr<AEffectWrapper> fx{};
98 
99  ossia::hash_map<int, ControlInlet*> controls;
100 
101  void removeControl(const Id<Process::Port>&);
102  void removeControl(int fxnum);
103 
104  //void addControl(int idx, float v) W_SIGNAL(addControl, idx, v);
105  void on_addControl(int idx, float v);
106  W_SLOT(on_addControl);
107  void on_addControl_impl(ControlInlet* inl);
108  void on_controlChangedFromScore(int num, float newval);
109 
110  void reloadControls();
111  void reloadPrograms();
112 
113  auto dispatch(
114  int32_t opcode, int32_t index = 0, intptr_t value = 0, void* ptr = nullptr,
115  float opt = 0.0f)
116  {
117  return fx->dispatch(opcode, index, value, ptr, opt);
118  }
119  std::atomic_bool needIdle{};
120 
121 private:
122  void loadPreset(const Process::Preset& preset) override;
123  Process::Preset savePreset() const noexcept override;
124  std::vector<Process::Preset> builtinPresets() const noexcept override;
125 
126  QString getString(AEffectOpcodes op, int param);
127  void setControlName(int fxnum, ControlInlet* ctrl);
128  void init();
129  void create();
130  void load();
131  void closePlugin();
132  void initFx();
133 
134  std::string m_backup_chunk;
135  ossia::float_vector m_backup_float_data;
136  std::vector<std::pair<std::string, int>> m_programs;
137  int32_t m_effectId{};
138  bool m_createControls{};
139 
140  struct vst_context_handler
141  {
142  Model& self;
143  explicit vst_context_handler(Model& self);
144  ~vst_context_handler();
145  } m_registration;
146 };
147 
148 // VSTModule* getPlugin(QString path);
149 AEffect* getPluginInstance(int32_t id);
150 intptr_t vst_host_callback(
151  AEffect* effect, int32_t opcode, int32_t index, intptr_t value, void* ptr,
152  float opt);
153 }
154 
155 namespace Process
156 {
157 template <>
158 QString EffectProcessFactory_T<vst::Model>::customConstructionData() const noexcept;
159 
160 template <>
161 Process::Descriptor
162 EffectProcessFactory_T<vst::Model>::descriptor(QString d) const noexcept;
163 }
164 
165 namespace vst
166 {
167 using VSTEffectFactory = Process::EffectProcessFactory_T<Model>;
168 }
Definition: QmlObjects.hpp:109
Definition: EffectFactory.hpp:14
Definition: score-lib-process/Process/Dataflow/Port.hpp:102
The Process class.
Definition: score-lib-process/Process/Process.hpp:61
The id_base_t class.
Definition: Identifier.hpp:57
Definition: Vst/Control.hpp:15
Definition: plugins/score-plugin-vst/Vst/commands.hpp:41
Base classes and tools to implement processes and layers.
Definition: JSONVisitor.hpp:1324
ProcessFlags
Various settings for processes.
Definition: ProcessFlags.hpp:17
Static metadata implementation.
Definition: lib/score/tools/Metadata.hpp:36
Definition: Preset.hpp:32
Definition: TimeValue.hpp:21